<s> import copy <EOL> import operator <EOL> import numbers <EOL> from collections import Hashable <EOL> from functools import partial <EOL> import pymongo <EOL> from bson import json_util , ObjectId <EOL> from bson . dbref import DBRef <EOL> from bson . son import SON <EOL> from mongoengine import signals <EOL> from mongoengine . common import _import_class <EOL> from mongoengine . errors import ( ValidationError , InvalidDocumentError , <EOL> LookUpError , FieldDoesNotExist ) <EOL> from mongoengine . python_support import PY3 , txt_type <EOL> from mongoengine . base . common import get_document , ALLOW_INHERITANCE <EOL> from mongoengine . base . datastructures import ( <EOL> BaseDict , <EOL> BaseList , <EOL> EmbeddedDocumentList , <EOL> StrictDict , <EOL> SemiStrictDict <EOL> ) <EOL> from mongoengine . base . fields import ComplexBaseField <EOL> __all__ = ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> NON_FIELD_ERRORS = '<STR_LIT>' <EOL> class BaseDocument ( object ) : <EOL> __slots__ = ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> _dynamic = False <EOL> _dynamic_lock = True <EOL> STRICT = False <EOL> def __init__ ( self , * args , ** values ) : <EOL> """<STR_LIT>""" <EOL> self . _initialised = False <EOL> self . _created = True <EOL> if args : <EOL> field = iter ( self . _fields_ordered ) <EOL> if getattr ( self , '<STR_LIT>' , False ) : <EOL> next ( field ) <EOL> for value in args : <EOL> name = next ( field ) <EOL> if name in values : <EOL> raise TypeError ( <EOL> "<STR_LIT>" + name + "<STR_LIT:'>" ) <EOL> values [ name ] = value <EOL> __auto_convert = values . pop ( "<STR_LIT>" , True ) <EOL> __only_fields = set ( values . pop ( "<STR_LIT>" , values ) ) <EOL> _created = values . pop ( "<STR_LIT>" , True ) <EOL> signals . pre_init . send ( self . __class__ , document = self , values = values ) <EOL> if not self . _dynamic and ( self . _meta . get ( '<STR_LIT:strict>' , True ) or _created ) : <EOL> for var in values . keys ( ) : <EOL> if var not in self . _fields . keys ( ) + [ '<STR_LIT:id>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] : <EOL> msg = ( <EOL> "<STR_LIT>" <EOL> ) . format ( var , self . _class_name ) <EOL> raise FieldDoesNotExist ( msg ) <EOL> if self . STRICT and not self . _dynamic : <EOL> self . _data = StrictDict . create ( allowed_keys = self . _fields_ordered ) ( ) <EOL> else : <EOL> self . _data = SemiStrictDict . create ( <EOL> allowed_keys = self . _fields_ordered ) ( ) <EOL> self . _dynamic_fields = SON ( ) <EOL> for key , field in self . _fields . iteritems ( ) : <EOL> if self . _db_field_map . get ( key , key ) in __only_fields : <EOL> continue <EOL> value = getattr ( self , key , None ) <EOL> setattr ( self , key , value ) <EOL> if "<STR_LIT>" not in values : <EOL> self . _cls = self . _class_name <EOL> if self . _dynamic : <EOL> dynamic_data = { } <EOL> for key , value in values . iteritems ( ) : <EOL> if key in self . _fields or key == '<STR_LIT>' : <EOL> setattr ( self , key , value ) <EOL> elif self . _dynamic : <EOL> dynamic_data [ key ] = value <EOL> else : <EOL> FileField = _import_class ( '<STR_LIT>' ) <EOL> for key , value in values . iteritems ( ) : <EOL> if key == '<STR_LIT>' : <EOL> continue <EOL> key = self . _reverse_db_field_map . get ( key , key ) <EOL> if key in self . _fields or key in ( '<STR_LIT:id>' , '<STR_LIT>' , '<STR_LIT>' ) : <EOL> if __auto_convert and value is not None : <EOL> field = self . _fields . get ( key ) <EOL> if field and not isinstance ( field , FileField ) : <EOL> value = field . to_python ( value ) <EOL> setattr ( self , key , value ) <EOL> else : <EOL> self . _data [ key ] = value <EOL> self . __set_field_display ( ) <EOL> if self . _dynamic : <EOL> self . _dynamic_lock = False <EOL> for key , value in dynamic_data . iteritems ( ) : <EOL> setattr ( self , key , value ) <EOL> self . _initialised = True <EOL> self . _created = _created <EOL> signals . post_init . send ( self . __class__ , document = self ) <EOL> def __delattr__ ( self , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> field_name = args [ <NUM_LIT:0> ] <EOL> if field_name in self . _fields : <EOL> default = self . _fields [ field_name ] . default <EOL> if callable ( default ) : <EOL> default = default ( ) <EOL> setattr ( self , field_name , default ) <EOL> else : <EOL> super ( BaseDocument , self ) . __delattr__ ( * args , ** kwargs ) <EOL> def __setattr__ ( self , name , value ) : <EOL> if self . _dynamic and not self . _dynamic_lock : <EOL> if not hasattr ( self , name ) and not name . startswith ( '<STR_LIT:_>' ) : <EOL> DynamicField = _import_class ( "<STR_LIT>" ) <EOL> field = DynamicField ( db_field = name ) <EOL> field . name = name <EOL> self . _dynamic_fields [ name ] = field <EOL> self . _fields_ordered += ( name , ) <EOL> if not name . startswith ( '<STR_LIT:_>' ) : <EOL> value = self . __expand_dynamic_values ( name , value ) <EOL> if name in self . _dynamic_fields : <EOL> self . _data [ name ] = value <EOL> if hasattr ( self , '<STR_LIT>' ) : <EOL> self . _mark_as_changed ( name ) <EOL> try : <EOL> self__created = self . _created <EOL> except AttributeError : <EOL> self__created = True <EOL> if ( self . _is_document and not self__created and <EOL> name in self . _meta . get ( '<STR_LIT>' , tuple ( ) ) and <EOL> self . _data . get ( name ) != value ) : <EOL> OperationError = _import_class ( '<STR_LIT>' ) <EOL> msg = "<STR_LIT>" % name <EOL> raise OperationError ( msg ) <EOL> try : <EOL> self__initialised = self . _initialised <EOL> except AttributeError : <EOL> self__initialised = False <EOL> if ( self . _is_document and self__initialised and <EOL> self__created and name == self . _meta . get ( '<STR_LIT>' ) ) : <EOL> super ( BaseDocument , self ) . __setattr__ ( '<STR_LIT>' , False ) <EOL> super ( BaseDocument , self ) . __setattr__ ( name , value ) <EOL> def __getstate__ ( self ) : <EOL> data = { } <EOL> for k in ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' ) : <EOL> if hasattr ( self , k ) : <EOL> data [ k ] = getattr ( self , k ) <EOL> data [ '<STR_LIT>' ] = self . to_mongo ( ) <EOL> return data <EOL> def __setstate__ ( self , data ) : <EOL> if isinstance ( data [ "<STR_LIT>" ] , SON ) : <EOL> data [ "<STR_LIT>" ] = self . __class__ . _from_son ( data [ "<STR_LIT>" ] ) . _data <EOL> for k in ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' ) : <EOL> if k in data : <EOL> setattr ( self , k , data [ k ] ) <EOL> if '<STR_LIT>' in data : <EOL> if self . _dynamic : <EOL> setattr ( self , '<STR_LIT>' , data [ '<STR_LIT>' ] ) <EOL> else : <EOL> _super_fields_ordered = type ( self ) . _fields_ordered <EOL> setattr ( self , '<STR_LIT>' , _super_fields_ordered ) <EOL> dynamic_fields = data . get ( '<STR_LIT>' ) or SON ( ) <EOL> for k in dynamic_fields . keys ( ) : <EOL> setattr ( self , k , data [ "<STR_LIT>" ] . get ( k ) ) <EOL> def __iter__ ( self ) : <EOL> return iter ( self . _fields_ordered ) <EOL> def __getitem__ ( self , name ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> if name in self . _fields_ordered : <EOL> return getattr ( self , name ) <EOL> except AttributeError : <EOL> pass <EOL> raise KeyError ( name ) <EOL> def __setitem__ ( self , name , value ) : <EOL> """<STR_LIT>""" <EOL> if not self . _dynamic and name not in self . _fields : <EOL> raise KeyError ( name ) <EOL> return setattr ( self , name , value ) <EOL> def __contains__ ( self , name ) : <EOL> try : <EOL> val = getattr ( self , name ) <EOL> return val is not None <EOL> except AttributeError : <EOL> return False <EOL> def __len__ ( self ) : <EOL> return len ( self . _data ) <EOL> def __repr__ ( self ) : <EOL> try : <EOL> u = self . __str__ ( ) <EOL> except ( UnicodeEncodeError , UnicodeDecodeError ) : <EOL> u = '<STR_LIT>' <EOL> repr_type = str if u is None else type ( u ) <EOL> return repr_type ( '<STR_LIT>' % ( self . __class__ . __name__ , u ) ) <EOL> def __str__ ( self ) : <EOL> if hasattr ( self , '<STR_LIT>' ) : <EOL> if PY3 : <EOL> return self . __unicode__ ( ) <EOL> else : <EOL> return unicode ( self ) . encode ( '<STR_LIT:utf-8>' ) <EOL> return txt_type ( '<STR_LIT>' % self . __class__ . __name__ ) <EOL> def __eq__ ( self , other ) : <EOL> if isinstance ( other , self . __class__ ) and hasattr ( other , '<STR_LIT:id>' ) and other . id is not None : <EOL> return self . id == other . id <EOL> if isinstance ( other , DBRef ) : <EOL> return self . _get_collection_name ( ) == other . collection and self . id == other . id <EOL> if self . id is None : <EOL> return self is other <EOL> return False <EOL> def __ne__ ( self , other ) : <EOL> return not self . __eq__ ( other ) <EOL> def __hash__ ( self ) : <EOL> if getattr ( self , '<STR_LIT>' , None ) is None : <EOL> return super ( BaseDocument , self ) . __hash__ ( ) <EOL> else : <EOL> return hash ( self . pk ) <EOL> def clean ( self ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def get_text_score ( self ) : <EOL> """<STR_LIT>""" <EOL> if '<STR_LIT>' not in self . _data : <EOL> raise InvalidDocumentError ( '<STR_LIT>' ) <EOL> return self . _data [ '<STR_LIT>' ] <EOL> def to_mongo ( self , use_db_field = True , fields = None ) : <EOL> """<STR_LIT>""" <EOL> if not fields : <EOL> fields = [ ] <EOL> data = SON ( ) <EOL> data [ "<STR_LIT>" ] = None <EOL> data [ '<STR_LIT>' ] = self . _class_name <EOL> EmbeddedDocumentField = _import_class ( "<STR_LIT>" ) <EOL> root_fields = set ( [ f . split ( '<STR_LIT:.>' ) [ <NUM_LIT:0> ] for f in fields ] ) <EOL> for field_name in self : <EOL> if root_fields and field_name not in root_fields : <EOL> continue <EOL> value = self . _data . get ( field_name , None ) <EOL> field = self . _fields . get ( field_name ) <EOL> if field is None and self . _dynamic : <EOL> field = self . _dynamic_fields . get ( field_name ) <EOL> if value is not None : <EOL> if fields : <EOL> key = '<STR_LIT>' % field_name <EOL> embedded_fields = [ <EOL> i . replace ( key , '<STR_LIT>' ) for i in fields <EOL> if i . startswith ( key ) ] <EOL> else : <EOL> embedded_fields = [ ] <EOL> value = field . to_mongo ( value , use_db_field = use_db_field , <EOL> fields = embedded_fields ) <EOL> if value is None and field . _auto_gen : <EOL> value = field . generate ( ) <EOL> self . _data [ field_name ] = value <EOL> if value is not None : <EOL> if use_db_field : <EOL> data [ field . db_field ] = value <EOL> else : <EOL> data [ field . name ] = value <EOL> Document = _import_class ( "<STR_LIT>" ) <EOL> if isinstance ( self , Document ) : <EOL> if data [ "<STR_LIT>" ] is None : <EOL> data [ "<STR_LIT>" ] = self . _data . get ( "<STR_LIT:id>" , None ) <EOL> if data [ '<STR_LIT>' ] is None : <EOL> data . pop ( '<STR_LIT>' ) <EOL> if ( not hasattr ( self , '<STR_LIT>' ) or <EOL> not self . _meta . get ( '<STR_LIT>' , ALLOW_INHERITANCE ) ) : <EOL> data . pop ( '<STR_LIT>' ) <EOL> return data <EOL> def validate ( self , clean = True ) : <EOL> """<STR_LIT>""" <EOL> errors = { } <EOL> if clean : <EOL> try : <EOL> self . clean ( ) <EOL> except ValidationError , error : <EOL> errors [ NON_FIELD_ERRORS ] = error <EOL> fields = [ ( self . _fields . get ( name , self . _dynamic_fields . get ( name ) ) , <EOL> self . _data . get ( name ) ) for name in self . _fields_ordered ] <EOL> EmbeddedDocumentField = _import_class ( "<STR_LIT>" ) <EOL> GenericEmbeddedDocumentField = _import_class ( <EOL> "<STR_LIT>" ) <EOL> for field , value in fields : <EOL> if value is not None : <EOL> try : <EOL> if isinstance ( field , ( EmbeddedDocumentField , <EOL> GenericEmbeddedDocumentField ) ) : <EOL> field . _validate ( value , clean = clean ) <EOL> else : <EOL> field . _validate ( value ) <EOL> except ValidationError , error : <EOL> errors [ field . name ] = error . errors or error <EOL> except ( ValueError , AttributeError , AssertionError ) , error : <EOL> errors [ field . name ] = error <EOL> elif field . required and not getattr ( field , '<STR_LIT>' , False ) : <EOL> errors [ field . name ] = ValidationError ( '<STR_LIT>' , <EOL> field_name = field . name ) <EOL> if errors : <EOL> pk = "<STR_LIT:None>" <EOL> if hasattr ( self , '<STR_LIT>' ) : <EOL> pk = self . pk <EOL> elif self . _instance and hasattr ( self . _instance , '<STR_LIT>' ) : <EOL> pk = self . _instance . pk <EOL> message = "<STR_LIT>" % ( self . _class_name , pk ) <EOL> raise ValidationError ( message , errors = errors ) <EOL> def to_json ( self , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> use_db_field = kwargs . pop ( '<STR_LIT>' , True ) <EOL> return json_util . dumps ( self . to_mongo ( use_db_field ) , * args , ** kwargs ) <EOL> @ classmethod <EOL> def from_json ( cls , json_data , created = False ) : <EOL> """<STR_LIT>""" <EOL> return cls . _from_son ( json_util . loads ( json_data ) , created = created ) <EOL> def __expand_dynamic_values ( self , name , value ) : <EOL> """<STR_LIT>""" <EOL> if not isinstance ( value , ( dict , list , tuple ) ) : <EOL> return value <EOL> EmbeddedDocumentListField = _import_class ( '<STR_LIT>' ) <EOL> is_list = False <EOL> if not hasattr ( value , '<STR_LIT>' ) : <EOL> is_list = True <EOL> value = dict ( [ ( k , v ) for k , v in enumerate ( value ) ] ) <EOL> if not is_list and '<STR_LIT>' in value : <EOL> cls = get_document ( value [ '<STR_LIT>' ] ) <EOL> return cls ( ** value ) <EOL> data = { } <EOL> for k , v in value . items ( ) : <EOL> key = name if is_list else k <EOL> data [ k ] = self . __expand_dynamic_values ( key , v ) <EOL> if is_list : <EOL> data_items = sorted ( data . items ( ) , key = operator . itemgetter ( <NUM_LIT:0> ) ) <EOL> value = [ v for k , v in data_items ] <EOL> else : <EOL> value = data <EOL> if ( isinstance ( value , ( list , tuple ) ) and <EOL> not isinstance ( value , BaseList ) ) : <EOL> if issubclass ( type ( self ) , EmbeddedDocumentListField ) : <EOL> value = EmbeddedDocumentList ( value , self , name ) <EOL> else : <EOL> value = BaseList ( value , self , name ) <EOL> elif isinstance ( value , dict ) and not isinstance ( value , BaseDict ) : <EOL> value = BaseDict ( value , self , name ) <EOL> return value <EOL> def _mark_as_changed ( self , key ) : <EOL> """<STR_LIT>""" <EOL> if not key : <EOL> return <EOL> if not hasattr ( self , '<STR_LIT>' ) : <EOL> return <EOL> if '<STR_LIT:.>' in key : <EOL> key , rest = key . split ( '<STR_LIT:.>' , <NUM_LIT:1> ) <EOL> key = self . _db_field_map . get ( key , key ) <EOL> key = '<STR_LIT>' % ( key , rest ) <EOL> else : <EOL> key = self . _db_field_map . get ( key , key ) <EOL> if key not in self . _changed_fields : <EOL> levels , idx = key . split ( '<STR_LIT:.>' ) , <NUM_LIT:1> <EOL> while idx <= len ( levels ) : <EOL> if '<STR_LIT:.>' . join ( levels [ : idx ] ) in self . _changed_fields : <EOL> break <EOL> idx += <NUM_LIT:1> <EOL> else : <EOL> self . _changed_fields . append ( key ) <EOL> level = '<STR_LIT:.>' . join ( levels [ : idx ] ) + '<STR_LIT:.>' <EOL> remove = self . _changed_fields . remove <EOL> for field in self . _changed_fields : <EOL> if field . startswith ( level ) : <EOL> remove ( field ) <EOL> def _clear_changed_fields ( self ) : <EOL> """<STR_LIT>""" <EOL> for changed in self . _get_changed_fields ( ) : <EOL> parts = changed . split ( "<STR_LIT:.>" ) <EOL> data = self <EOL> for part in parts : <EOL> if isinstance ( data , list ) : <EOL> try : <EOL> data = data [ int ( part ) ] <EOL> except IndexError : <EOL> data = None <EOL> elif isinstance ( data , dict ) : <EOL> data = data . get ( part , None ) <EOL> else : <EOL> data = getattr ( data , part , None ) <EOL> if hasattr ( data , "<STR_LIT>" ) : <EOL> if hasattr ( data , "<STR_LIT>" ) and data . _is_document : <EOL> continue <EOL> data . _changed_fields = [ ] <EOL> self . _changed_fields = [ ] <EOL> def _nestable_types_changed_fields ( self , changed_fields , key , data , inspected ) : <EOL> if not hasattr ( data , '<STR_LIT>' ) : <EOL> iterator = enumerate ( data ) <EOL> else : <EOL> iterator = data . iteritems ( ) <EOL> for index , value in iterator : <EOL> list_key = "<STR_LIT>" % ( key , index ) <EOL> if list_key [ : - <NUM_LIT:1> ] in changed_fields : <EOL> continue <EOL> if hasattr ( value , '<STR_LIT>' ) : <EOL> changed = value . _get_changed_fields ( inspected ) <EOL> changed_fields += [ "<STR_LIT>" % ( list_key , k ) <EOL> for k in changed if k ] <EOL> elif isinstance ( value , ( list , tuple , dict ) ) : <EOL> self . _nestable_types_changed_fields ( <EOL> changed_fields , list_key , value , inspected ) <EOL> def _get_changed_fields ( self , inspected = None ) : <EOL> """<STR_LIT>""" <EOL> EmbeddedDocument = _import_class ( "<STR_LIT>" ) <EOL> DynamicEmbeddedDocument = _import_class ( "<STR_LIT>" ) <EOL> ReferenceField = _import_class ( "<STR_LIT>" ) <EOL> SortedListField = _import_class ( "<STR_LIT>" ) <EOL> changed_fields = [ ] <EOL> changed_fields += getattr ( self , '<STR_LIT>' , [ ] ) <EOL> inspected = inspected or set ( ) <EOL> if hasattr ( self , '<STR_LIT:id>' ) and isinstance ( self . id , Hashable ) : <EOL> if self . id in inspected : <EOL> return changed_fields <EOL> inspected . add ( self . id ) <EOL> for field_name in self . _fields_ordered : <EOL> db_field_name = self . _db_field_map . get ( field_name , field_name ) <EOL> key = '<STR_LIT>' % db_field_name <EOL> data = self . _data . get ( field_name , None ) <EOL> field = self . _fields . get ( field_name ) <EOL> if hasattr ( data , '<STR_LIT:id>' ) : <EOL> if data . id in inspected : <EOL> continue <EOL> if isinstance ( field , ReferenceField ) : <EOL> continue <EOL> elif ( isinstance ( data , ( EmbeddedDocument , DynamicEmbeddedDocument ) ) <EOL> and db_field_name not in changed_fields ) : <EOL> changed = data . _get_changed_fields ( inspected ) <EOL> changed_fields += [ "<STR_LIT>" % ( key , k ) for k in changed if k ] <EOL> elif ( isinstance ( data , ( list , tuple , dict ) ) and <EOL> db_field_name not in changed_fields ) : <EOL> if ( hasattr ( field , '<STR_LIT>' ) and <EOL> isinstance ( field . field , ReferenceField ) ) : <EOL> continue <EOL> elif isinstance ( field , SortedListField ) and field . _ordering : <EOL> if any ( map ( lambda d : field . _ordering in d . _changed_fields , data ) ) : <EOL> changed_fields . append ( db_field_name ) <EOL> continue <EOL> self . _nestable_types_changed_fields ( <EOL> changed_fields , key , data , inspected ) <EOL> return changed_fields <EOL> def _delta ( self ) : <EOL> """<STR_LIT>""" <EOL> doc = self . to_mongo ( ) <EOL> set_fields = self . _get_changed_fields ( ) <EOL> unset_data = { } <EOL> parts = [ ] <EOL> if hasattr ( self , '<STR_LIT>' ) : <EOL> set_data = { } <EOL> for path in set_fields : <EOL> parts = path . split ( '<STR_LIT:.>' ) <EOL> d = doc <EOL> new_path = [ ] <EOL> for p in parts : <EOL> if isinstance ( d , ( ObjectId , DBRef ) ) : <EOL> break <EOL> elif isinstance ( d , list ) and p . isdigit ( ) : <EOL> try : <EOL> d = d [ int ( p ) ] <EOL> except IndexError : <EOL> d = None <EOL> elif hasattr ( d , '<STR_LIT>' ) : <EOL> d = d . get ( p ) <EOL> new_path . append ( p ) <EOL> path = '<STR_LIT:.>' . join ( new_path ) <EOL> set_data [ path ] = d <EOL> else : <EOL> set_data = doc <EOL> if '<STR_LIT>' in set_data : <EOL> del set_data [ '<STR_LIT>' ] <EOL> for path , value in set_data . items ( ) : <EOL> if value or isinstance ( value , ( numbers . Number , bool ) ) : <EOL> continue <EOL> default = None <EOL> if ( self . _dynamic and len ( parts ) and parts [ <NUM_LIT:0> ] in <EOL> self . _dynamic_fields ) : <EOL> del set_data [ path ] <EOL> unset_data [ path ] = <NUM_LIT:1> <EOL> continue <EOL> elif path in self . _fields : <EOL> default = self . _fields [ path ] . default <EOL> else : <EOL> d = self <EOL> parts = path . split ( '<STR_LIT:.>' ) <EOL> db_field_name = parts . pop ( ) <EOL> for p in parts : <EOL> if isinstance ( d , list ) and p . isdigit ( ) : <EOL> d = d [ int ( p ) ] <EOL> elif ( hasattr ( d , '<STR_LIT>' ) and <EOL> not isinstance ( d , dict ) ) : <EOL> real_path = d . _reverse_db_field_map . get ( p , p ) <EOL> d = getattr ( d , real_path ) <EOL> else : <EOL> d = d . get ( p ) <EOL> if hasattr ( d , '<STR_LIT>' ) : <EOL> field_name = d . _reverse_db_field_map . get ( db_field_name , <EOL> db_field_name ) <EOL> if field_name in d . _fields : <EOL> default = d . _fields . get ( field_name ) . default <EOL> else : <EOL> default = None <EOL> if default is not None : <EOL> if callable ( default ) : <EOL> default = default ( ) <EOL> if default != value : <EOL> continue <EOL> del set_data [ path ] <EOL> unset_data [ path ] = <NUM_LIT:1> <EOL> return set_data , unset_data <EOL> @ classmethod <EOL> def _get_collection_name ( cls ) : <EOL> """<STR_LIT>""" <EOL> return cls . _meta . get ( '<STR_LIT>' , None ) <EOL> @ classmethod <EOL> def _from_son ( cls , son , _auto_dereference = True , only_fields = None , created = False ) : <EOL> """<STR_LIT>""" <EOL> if not only_fields : <EOL> only_fields = [ ] <EOL> class_name = son . get ( '<STR_LIT>' , cls . _class_name ) <EOL> data = dict ( ( "<STR_LIT:%s>" % key , value ) for key , value in son . iteritems ( ) ) <EOL> if class_name != cls . _class_name : <EOL> cls = get_document ( class_name ) <EOL> changed_fields = [ ] <EOL> errors_dict = { } <EOL> fields = cls . _fields <EOL> if not _auto_dereference : <EOL> fields = copy . copy ( fields ) <EOL> for field_name , field in fields . iteritems ( ) : <EOL> field . _auto_dereference = _auto_dereference <EOL> if field . db_field in data : <EOL> value = data [ field . db_field ] <EOL> try : <EOL> data [ field_name ] = ( value if value is None <EOL> else field . to_python ( value ) ) <EOL> if field_name != field . db_field : <EOL> del data [ field . db_field ] <EOL> except ( AttributeError , ValueError ) , e : <EOL> errors_dict [ field_name ] = e <EOL> elif field . default : <EOL> default = field . default <EOL> if callable ( default ) : <EOL> default = default ( ) <EOL> if isinstance ( default , BaseDocument ) : <EOL> changed_fields . append ( field_name ) <EOL> elif not only_fields or field_name in only_fields : <EOL> changed_fields . append ( field_name ) <EOL> if errors_dict : <EOL> errors = "<STR_LIT:\n>" . join ( [ "<STR_LIT>" % ( k , v ) <EOL> for k , v in errors_dict . items ( ) ] ) <EOL> msg = ( "<STR_LIT>" <EOL> % ( cls . _class_name , errors ) ) <EOL> raise InvalidDocumentError ( msg ) <EOL> if cls . STRICT : <EOL> data = dict ( ( k , v ) <EOL> for k , v in data . iteritems ( ) if k in cls . _fields ) <EOL> obj = cls ( __auto_convert = False , _created = created , __only_fields = only_fields , ** data ) <EOL> obj . _changed_fields = changed_fields <EOL> if not _auto_dereference : <EOL> obj . _fields = fields <EOL> return obj <EOL> @ classmethod <EOL> def _build_index_specs ( cls , meta_indexes ) : <EOL> """<STR_LIT>""" <EOL> geo_indices = cls . _geo_indices ( ) <EOL> unique_indices = cls . _unique_with_indexes ( ) <EOL> index_specs = [ cls . _build_index_spec ( spec ) <EOL> for spec in meta_indexes ] <EOL> def merge_index_specs ( index_specs , indices ) : <EOL> if not indices : <EOL> return index_specs <EOL> spec_fields = [ v [ '<STR_LIT>' ] <EOL> for k , v in enumerate ( index_specs ) ] <EOL> for k , v in enumerate ( indices ) : <EOL> if v [ '<STR_LIT>' ] in spec_fields : <EOL> index_specs [ spec_fields . index ( v [ '<STR_LIT>' ] ) ] . update ( v ) <EOL> else : <EOL> index_specs . append ( v ) <EOL> return index_specs <EOL> index_specs = merge_index_specs ( index_specs , geo_indices ) <EOL> index_specs = merge_index_specs ( index_specs , unique_indices ) <EOL> return index_specs <EOL> @ classmethod <EOL> def _build_index_spec ( cls , spec ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( spec , basestring ) : <EOL> spec = { '<STR_LIT>' : [ spec ] } <EOL> elif isinstance ( spec , ( list , tuple ) ) : <EOL> spec = { '<STR_LIT>' : list ( spec ) } <EOL> elif isinstance ( spec , dict ) : <EOL> spec = dict ( spec ) <EOL> index_list = [ ] <EOL> direction = None <EOL> allow_inheritance = cls . _meta . get ( '<STR_LIT>' , <EOL> ALLOW_INHERITANCE ) <EOL> include_cls = ( allow_inheritance and not spec . get ( '<STR_LIT>' , False ) and <EOL> spec . get ( '<STR_LIT>' , True ) and '<STR_LIT>' not in spec [ '<STR_LIT>' ] ) <EOL> include_cls = include_cls and ( spec . get ( '<STR_LIT>' , False ) or cls . _meta . get ( '<STR_LIT>' , True ) ) <EOL> if "<STR_LIT>" in spec : <EOL> spec . pop ( '<STR_LIT>' ) <EOL> for key in spec [ '<STR_LIT>' ] : <EOL> if isinstance ( key , ( list , tuple ) ) : <EOL> continue <EOL> direction = pymongo . ASCENDING <EOL> if key . startswith ( "<STR_LIT:->" ) : <EOL> direction = pymongo . DESCENDING <EOL> elif key . startswith ( "<STR_LIT:$>" ) : <EOL> direction = pymongo . TEXT <EOL> elif key . startswith ( "<STR_LIT:#>" ) : <EOL> direction = pymongo . HASHED <EOL> elif key . startswith ( "<STR_LIT:(>" ) : <EOL> direction = pymongo . GEOSPHERE <EOL> elif key . startswith ( "<STR_LIT:)>" ) : <EOL> direction = pymongo . GEOHAYSTACK <EOL> elif key . startswith ( "<STR_LIT:*>" ) : <EOL> direction = pymongo . GEO2D <EOL> if key . startswith ( ( "<STR_LIT:+>" , "<STR_LIT:->" , "<STR_LIT:*>" , "<STR_LIT:$>" , "<STR_LIT:#>" , "<STR_LIT:(>" , "<STR_LIT:)>" ) ) : <EOL> key = key [ <NUM_LIT:1> : ] <EOL> parts = key . split ( '<STR_LIT:.>' ) <EOL> if parts in ( [ '<STR_LIT>' ] , [ '<STR_LIT:id>' ] , [ '<STR_LIT>' ] ) : <EOL> key = '<STR_LIT>' <EOL> else : <EOL> fields = cls . _lookup_field ( parts ) <EOL> parts = [ ] <EOL> for field in fields : <EOL> try : <EOL> if field != "<STR_LIT>" : <EOL> field = field . db_field <EOL> except AttributeError : <EOL> pass <EOL> parts . append ( field ) <EOL> key = '<STR_LIT:.>' . join ( parts ) <EOL> index_list . append ( ( key , direction ) ) <EOL> if include_cls and direction not in ( <EOL> pymongo . GEO2D , pymongo . GEOHAYSTACK , pymongo . GEOSPHERE ) : <EOL> index_list . insert ( <NUM_LIT:0> , ( '<STR_LIT>' , <NUM_LIT:1> ) ) <EOL> if index_list : <EOL> spec [ '<STR_LIT>' ] = index_list <EOL> return spec <EOL> @ classmethod <EOL> def _unique_with_indexes ( cls , namespace = "<STR_LIT>" ) : <EOL> """<STR_LIT>""" <EOL> unique_indexes = [ ] <EOL> for field_name , field in cls . _fields . items ( ) : <EOL> sparse = field . sparse <EOL> if field . unique : <EOL> unique_fields = [ field . db_field ] <EOL> if field . unique_with : <EOL> if isinstance ( field . unique_with , basestring ) : <EOL> field . unique_with = [ field . unique_with ] <EOL> unique_with = [ ] <EOL> for other_name in field . unique_with : <EOL> parts = other_name . split ( '<STR_LIT:.>' ) <EOL> parts = cls . _lookup_field ( parts ) <EOL> name_parts = [ part . db_field for part in parts ] <EOL> unique_with . append ( '<STR_LIT:.>' . join ( name_parts ) ) <EOL> parts [ - <NUM_LIT:1> ] . required = True <EOL> sparse = ( not sparse and <EOL> parts [ - <NUM_LIT:1> ] . name not in cls . __dict__ ) <EOL> unique_fields += unique_with <EOL> fields = [ ( "<STR_LIT>" % ( namespace , f ) , pymongo . ASCENDING ) <EOL> for f in unique_fields ] <EOL> index = { '<STR_LIT>' : fields , '<STR_LIT>' : True , '<STR_LIT>' : sparse } <EOL> unique_indexes . append ( index ) <EOL> if field . __class__ . __name__ == "<STR_LIT>" : <EOL> field = field . field <EOL> if ( field . __class__ . __name__ == "<STR_LIT>" and <EOL> field . document_type != cls ) : <EOL> field_namespace = "<STR_LIT>" % field_name <EOL> doc_cls = field . document_type <EOL> unique_indexes += doc_cls . _unique_with_indexes ( field_namespace ) <EOL> return unique_indexes <EOL> @ classmethod <EOL> def _geo_indices ( cls , inspected = None , parent_field = None ) : <EOL> inspected = inspected or [ ] <EOL> geo_indices = [ ] <EOL> inspected . append ( cls ) <EOL> geo_field_type_names = [ "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" ] <EOL> geo_field_types = tuple ( [ _import_class ( field ) <EOL> for field in geo_field_type_names ] ) <EOL> for field in cls . _fields . values ( ) : <EOL> if not isinstance ( field , geo_field_types ) : <EOL> continue <EOL> if hasattr ( field , '<STR_LIT>' ) : <EOL> field_cls = field . document_type <EOL> if field_cls in inspected : <EOL> continue <EOL> if hasattr ( field_cls , '<STR_LIT>' ) : <EOL> geo_indices += field_cls . _geo_indices ( <EOL> inspected , parent_field = field . db_field ) <EOL> elif field . _geo_index : <EOL> field_name = field . db_field <EOL> if parent_field : <EOL> field_name = "<STR_LIT>" % ( parent_field , field_name ) <EOL> geo_indices . append ( { '<STR_LIT>' : <EOL> [ ( field_name , field . _geo_index ) ] } ) <EOL> return geo_indices <EOL> @ classmethod <EOL> def _lookup_field ( cls , parts ) : <EOL> """<STR_LIT>""" <EOL> ListField = _import_class ( "<STR_LIT>" ) <EOL> DynamicField = _import_class ( '<STR_LIT>' ) <EOL> if not isinstance ( parts , ( list , tuple ) ) : <EOL> parts = [ parts ] <EOL> fields = [ ] <EOL> field = None <EOL> for field_name in parts : <EOL> if field_name . isdigit ( ) and isinstance ( field , ListField ) : <EOL> fields . append ( field_name ) <EOL> continue <EOL> if field is None : <EOL> if field_name == '<STR_LIT>' : <EOL> field_name = cls . _meta [ '<STR_LIT>' ] <EOL> if field_name in cls . _fields : <EOL> field = cls . _fields [ field_name ] <EOL> elif cls . _dynamic : <EOL> field = DynamicField ( db_field = field_name ) <EOL> elif cls . _meta . get ( "<STR_LIT>" , False ) or cls . _meta . get ( "<STR_LIT>" , False ) : <EOL> for subcls in cls . __subclasses__ ( ) : <EOL> try : <EOL> field = subcls . _lookup_field ( [ field_name ] ) [ <NUM_LIT:0> ] <EOL> except LookUpError : <EOL> continue <EOL> if field is not None : <EOL> break <EOL> else : <EOL> raise LookUpError ( '<STR_LIT>' % field_name ) <EOL> else : <EOL> raise LookUpError ( '<STR_LIT>' <EOL> % field_name ) <EOL> else : <EOL> ReferenceField = _import_class ( '<STR_LIT>' ) <EOL> GenericReferenceField = _import_class ( '<STR_LIT>' ) <EOL> if isinstance ( field , ( ReferenceField , GenericReferenceField ) ) : <EOL> raise LookUpError ( '<STR_LIT>' % <EOL> '<STR_LIT>' . join ( parts ) ) <EOL> if hasattr ( getattr ( field , '<STR_LIT>' , None ) , '<STR_LIT>' ) : <EOL> new_field = field . field . lookup_member ( field_name ) <EOL> elif cls . _dynamic and ( isinstance ( field , DynamicField ) or <EOL> getattr ( getattr ( field , '<STR_LIT>' ) , '<STR_LIT>' ) ) : <EOL> new_field = DynamicField ( db_field = field_name ) <EOL> else : <EOL> try : <EOL> new_field = field . lookup_member ( field_name ) <EOL> except AttributeError : <EOL> raise LookUpError ( '<STR_LIT>' <EOL> '<STR_LIT>' . format ( <EOL> field_name , field . name ) ) <EOL> if not new_field and isinstance ( field , ComplexBaseField ) : <EOL> fields . append ( field_name ) <EOL> continue <EOL> elif not new_field : <EOL> raise LookUpError ( '<STR_LIT>' <EOL> % field_name ) <EOL> field = new_field <EOL> fields . append ( field ) <EOL> return fields <EOL> @ classmethod <EOL> def _translate_field_name ( cls , field , sep = '<STR_LIT:.>' ) : <EOL> """<STR_LIT>""" <EOL> parts = field . split ( sep ) <EOL> parts = [ f . db_field for f in cls . _lookup_field ( parts ) ] <EOL> return '<STR_LIT:.>' . join ( parts ) <EOL> def __set_field_display ( self ) : <EOL> """<STR_LIT>""" <EOL> for attr_name , field in self . _fields . items ( ) : <EOL> if field . choices : <EOL> if self . _dynamic : <EOL> obj = self <EOL> else : <EOL> obj = type ( self ) <EOL> setattr ( obj , <EOL> '<STR_LIT>' % attr_name , <EOL> partial ( self . __get_field_display , field = field ) ) <EOL> def __get_field_display ( self , field ) : <EOL> """<STR_LIT>""" <EOL> value = getattr ( self , field . name ) <EOL> if field . choices and isinstance ( field . choices [ <NUM_LIT:0> ] , ( list , tuple ) ) : <EOL> return dict ( field . choices ) . get ( value , value ) <EOL> return value </s>
