<s> from __future__ import absolute_import <EOL> import six <EOL> import inspect <EOL> from . exceptions import BadValueError <EOL> function_name = None <EOL> if six . PY3 : <EOL> def function_name ( f ) : <EOL> return f . __name__ <EOL> else : <EOL> def function_name ( f ) : <EOL> return f . func_name <EOL> class JsonProperty ( object ) : <EOL> default = None <EOL> type_config = None <EOL> def __init__ ( self , default = Ellipsis , name = None , choices = None , <EOL> required = False , exclude_if_none = False , validators = None , <EOL> verbose_name = None , type_config = None ) : <EOL> validators = validators or ( ) <EOL> self . name = name <EOL> if default is Ellipsis : <EOL> default = self . default <EOL> if callable ( default ) : <EOL> self . default = default <EOL> else : <EOL> self . default = lambda : default <EOL> self . choices = choices <EOL> self . choice_keys = [ ] <EOL> if choices : <EOL> for choice in choices : <EOL> if isinstance ( choice , tuple ) : <EOL> choice , _ = choice <EOL> self . choice_keys . append ( choice ) <EOL> self . required = required <EOL> self . exclude_if_none = exclude_if_none <EOL> self . _validators = validators <EOL> self . verbose_name = verbose_name <EOL> if type_config : <EOL> self . type_config = type_config <EOL> def init_property ( self , default_name , type_config ) : <EOL> self . name = self . name or default_name <EOL> self . type_config = self . type_config or type_config <EOL> def wrap ( self , obj ) : <EOL> raise NotImplementedError ( ) <EOL> def unwrap ( self , obj ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( ) <EOL> def to_json ( self , value ) : <EOL> _ , unwrapped = self . unwrap ( value ) <EOL> return unwrapped <EOL> def to_python ( self , value ) : <EOL> return self . wrap ( value ) <EOL> def __get__ ( self , instance , owner ) : <EOL> if instance : <EOL> assert self . name in instance <EOL> return instance [ self . name ] <EOL> else : <EOL> return self <EOL> def __set__ ( self , instance , value ) : <EOL> instance [ self . name ] = value <EOL> def __call__ ( self , method ) : <EOL> """<STR_LIT>""" <EOL> assert self . default ( ) is None <EOL> self . default = method <EOL> self . name = self . name or function_name ( method ) <EOL> return self <EOL> def exclude ( self , value ) : <EOL> return self . exclude_if_none and not value <EOL> def empty ( self , value ) : <EOL> return value is None <EOL> def validate ( self , value , required = True , recursive = True ) : <EOL> if ( self . choice_keys and value not in self . choice_keys <EOL> and value is not None ) : <EOL> raise BadValueError ( <EOL> '<STR_LIT>' . format ( value , self . choice_keys ) <EOL> ) <EOL> if not self . empty ( value ) : <EOL> self . _custom_validate ( value ) <EOL> elif required and self . required : <EOL> raise BadValueError ( <EOL> '<STR_LIT>' . format ( self . name ) <EOL> ) <EOL> if recursive and hasattr ( value , '<STR_LIT>' ) : <EOL> value . validate ( required = required ) <EOL> def _custom_validate ( self , value ) : <EOL> if self . _validators : <EOL> if hasattr ( self . _validators , '<STR_LIT>' ) : <EOL> for validator in self . _validators : <EOL> validator ( value ) <EOL> else : <EOL> self . _validators ( value ) <EOL> class JsonContainerProperty ( JsonProperty ) : <EOL> _type = default = None <EOL> container_class = None <EOL> def __init__ ( self , item_type = None , ** kwargs ) : <EOL> self . _item_type_deferred = item_type <EOL> super ( JsonContainerProperty , self ) . __init__ ( ** kwargs ) <EOL> def init_property ( self , ** kwargs ) : <EOL> super ( JsonContainerProperty , self ) . init_property ( ** kwargs ) <EOL> if not inspect . isfunction ( self . _item_type_deferred ) : <EOL> self . item_type <EOL> def set_item_type ( self , item_type ) : <EOL> from jsonobject . base import JsonObjectMeta <EOL> if hasattr ( item_type , '<STR_LIT>' ) : <EOL> item_type = item_type . _type <EOL> if isinstance ( item_type , tuple ) : <EOL> item_type = item_type [ <NUM_LIT:0> ] <EOL> allowed_types = set ( self . type_config . properties . keys ( ) ) <EOL> if isinstance ( item_type , JsonObjectMeta ) or not item_type or item_type in allowed_types : <EOL> self . _item_type = item_type <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" . format ( <EOL> item_type , <EOL> allowed_types , <EOL> ) ) <EOL> @ property <EOL> def item_type ( self ) : <EOL> if hasattr ( self , '<STR_LIT>' ) : <EOL> if inspect . isfunction ( self . _item_type_deferred ) : <EOL> self . set_item_type ( self . _item_type_deferred ( ) ) <EOL> else : <EOL> self . set_item_type ( self . _item_type_deferred ) <EOL> del self . _item_type_deferred <EOL> return self . _item_type <EOL> def empty ( self , value ) : <EOL> return not value <EOL> def wrap ( self , obj ) : <EOL> wrapper = self . type_to_property ( self . item_type ) if self . item_type else None <EOL> return self . container_class ( obj , wrapper = wrapper , <EOL> type_config = self . type_config ) <EOL> def type_to_property ( self , item_type ) : <EOL> map_types_properties = self . type_config . properties <EOL> from . properties import ObjectProperty <EOL> from . base import JsonObjectBase <EOL> if issubclass ( item_type , JsonObjectBase ) : <EOL> return ObjectProperty ( item_type , type_config = self . type_config ) <EOL> elif item_type in map_types_properties : <EOL> return map_types_properties [ item_type ] ( type_config = self . type_config ) <EOL> else : <EOL> for key , value in map_types_properties . items ( ) : <EOL> if issubclass ( item_type , key ) : <EOL> return value ( type_config = self . type_config ) <EOL> raise TypeError ( '<STR_LIT>' . format ( item_type ) ) <EOL> def unwrap ( self , obj ) : <EOL> if not isinstance ( obj , self . _type ) : <EOL> raise BadValueError ( <EOL> '<STR_LIT>' . format ( <EOL> obj , self . _type . __name__ ) <EOL> ) <EOL> if isinstance ( obj , self . container_class ) : <EOL> return obj , obj . _obj <EOL> else : <EOL> wrapped = self . wrap ( self . _type ( ) ) <EOL> self . _update ( wrapped , obj ) <EOL> return self . unwrap ( wrapped ) <EOL> def _update ( self , container , extension ) : <EOL> raise NotImplementedError ( ) <EOL> class DefaultProperty ( JsonProperty ) : <EOL> def wrap ( self , obj ) : <EOL> assert self . type_config . string_conversions is not None <EOL> value = self . value_to_python ( obj ) <EOL> property_ = self . value_to_property ( value ) <EOL> if property_ : <EOL> return property_ . wrap ( obj ) <EOL> def unwrap ( self , obj ) : <EOL> property_ = self . value_to_property ( obj ) <EOL> if property_ : <EOL> return property_ . unwrap ( obj ) <EOL> else : <EOL> return obj , None <EOL> def value_to_property ( self , value ) : <EOL> map_types_properties = self . type_config . properties <EOL> if value is None : <EOL> return None <EOL> elif type ( value ) in map_types_properties : <EOL> return map_types_properties [ type ( value ) ] ( <EOL> type_config = self . type_config ) <EOL> else : <EOL> for value_type , prop_class in map_types_properties . items ( ) : <EOL> if isinstance ( value , value_type ) : <EOL> return prop_class ( type_config = self . type_config ) <EOL> else : <EOL> raise BadValueError ( <EOL> '<STR_LIT>' . format ( <EOL> value , map_types_properties . keys ( ) ) <EOL> ) <EOL> def value_to_python ( self , value ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( value , six . string_types ) : <EOL> convert = None <EOL> for pattern , _convert in self . type_config . string_conversions : <EOL> if pattern . match ( value ) : <EOL> convert = _convert <EOL> break <EOL> if convert is not None : <EOL> try : <EOL> value = convert ( value ) <EOL> except Exception : <EOL> pass <EOL> return value <EOL> class AssertTypeProperty ( JsonProperty ) : <EOL> _type = None <EOL> def assert_type ( self , obj ) : <EOL> if not isinstance ( obj , self . _type ) : <EOL> raise BadValueError ( <EOL> '<STR_LIT>' . format ( obj , self . _type ) <EOL> ) <EOL> def selective_coerce ( self , obj ) : <EOL> return obj <EOL> def wrap ( self , obj ) : <EOL> obj = self . selective_coerce ( obj ) <EOL> self . assert_type ( obj ) <EOL> return obj <EOL> def unwrap ( self , obj ) : <EOL> obj = self . selective_coerce ( obj ) <EOL> self . assert_type ( obj ) <EOL> return obj , obj <EOL> class AbstractDateProperty ( JsonProperty ) : <EOL> _type = None <EOL> def __init__ ( self , exact = False , * args , ** kwargs ) : <EOL> super ( AbstractDateProperty , self ) . __init__ ( * args , ** kwargs ) <EOL> self . exact = exact <EOL> def wrap ( self , obj ) : <EOL> try : <EOL> if not isinstance ( obj , six . string_types ) : <EOL> raise ValueError ( ) <EOL> return self . _wrap ( obj ) <EOL> except ValueError : <EOL> raise BadValueError ( '<STR_LIT>' . format ( <EOL> obj , <EOL> self . _type . __name__ , <EOL> ) ) <EOL> def unwrap ( self , obj ) : <EOL> if not isinstance ( obj , self . _type ) : <EOL> raise BadValueError ( '<STR_LIT>' . format ( <EOL> obj , <EOL> self . _type . __name__ , <EOL> ) ) <EOL> return self . _unwrap ( obj ) <EOL> def _wrap ( self , obj ) : <EOL> raise NotImplementedError ( ) <EOL> def _unwrap ( self , obj ) : <EOL> raise NotImplementedError ( ) </s>
