<s> import os <EOL> import logging <EOL> import pson <EOL> class SettingExistsException ( Exception ) : <EOL> def __init__ ( self , k ) : <EOL> Exception . __init__ ( self , k ) <EOL> class SettingDoesntExistException ( Exception ) : <EOL> def __init__ ( self , k ) : <EOL> Exception . __init__ ( self , k ) <EOL> class Settings ( object ) : <EOL> def __init__ ( self , settings_file ) : <EOL> self . _types = { } <EOL> self . _values = { } <EOL> self . _change_fns = { } <EOL> self . _temp_values = { } <EOL> self . _used_default = set ( ) <EOL> self . _unresolved_values = None <EOL> self . _settings_file = settings_file <EOL> self . _load ( settings_file ) <EOL> self . _delayed_save = False <EOL> self . _enqueued_save_abort_flag = None <EOL> self . _initialized = True <EOL> def set_delayed_save ( self , v ) : <EOL> assert type ( v ) == bool <EOL> self . _delayed_save = v <EOL> def _load ( self , settings_file = None ) : <EOL> self . _unresolved_values = { } <EOL> if not os . path . exists ( settings_file ) : <EOL> return <EOL> contents = open ( settings_file , "<STR_LIT:r>" ) . read ( ) <EOL> if len ( contents ) : <EOL> try : <EOL> something = pson . loads ( contents ) <EOL> except Exception : <EOL> logging . warning ( "<STR_LIT>" , settings_file ) <EOL> return <EOL> else : <EOL> return <EOL> if type ( something ) != dict : <EOL> logging . warning ( "<STR_LIT>" , settings_file ) <EOL> return <EOL> self . _unresolved_values = something <EOL> def _set_dirty ( self ) : <EOL> if self . _delayed_save : <EOL> if self . _enqueued_save_abort_flag : <EOL> self . _enqueued_save_abort_flag . set ( True ) <EOL> def do_delayed_save ( abort_flag ) : <EOL> if abort_flag . get ( ) : <EOL> return <EOL> assert abort_flag == self . _enqueued_save_abort_flag <EOL> self . _enqueued_save_abort_flag = None <EOL> self . _do_save ( ) <EOL> flag = BoxedObject ( False ) <EOL> self . _enqueued_save_abort_flag = flag <EOL> MessageLoop . add_delayed_message ( do_delayed_save , <NUM_LIT:1000> , flag ) <EOL> else : <EOL> self . _do_save ( ) <EOL> def _do_save ( self ) : <EOL> logging . info ( "<STR_LIT>" , self . _settings_file ) <EOL> if os . path . exists ( self . _settings_file ) : <EOL> import stat <EOL> os . chmod ( self . _settings_file , stat . S_IREAD | stat . S_IWRITE ) <EOL> flags = os . O_WRONLY | os . O_CREAT <EOL> with os . fdopen ( os . open ( self . _settings_file , flags , <NUM_LIT:0> <NUM_LIT> ) , "<STR_LIT:w>" ) as f : <EOL> vals = { } <EOL> for k in self . _values . keys ( ) : <EOL> if k not in self . _used_default : <EOL> vals [ k ] = self . _values [ k ] <EOL> s = pson . dumps ( vals , pretty = True ) <EOL> f . write ( s ) <EOL> def has_setting ( self , k ) : <EOL> return self . _types . has_key ( k ) <EOL> def register ( self , k , ty , default , change_fn = None ) : <EOL> if self . _types . has_key ( k ) : <EOL> if self . _types [ k ] != ty : <EOL> raise Exception ( "<STR_LIT>" % ( k , ty ) ) <EOL> return <EOL> if default != None and type ( default ) != ty : <EOL> raise Exception ( "<STR_LIT>" % ( ty , type ( default ) ) ) <EOL> self . _types [ k ] = ty <EOL> self . _change_fns [ k ] = change_fn <EOL> assert ( not self . _values . has_key ( k ) ) <EOL> if self . _unresolved_values . has_key ( k ) : <EOL> v = self . _unresolved_values [ k ] <EOL> if isinstance ( v , self . _types [ k ] ) == False : <EOL> self . _values [ k ] = default <EOL> self . _used_default . add ( k ) <EOL> else : <EOL> self . _values [ k ] = v <EOL> del self . _unresolved_values [ k ] <EOL> else : <EOL> self . _values [ k ] = default <EOL> self . _used_default . add ( k ) <EOL> def is_manually_set ( self , k ) : <EOL> if self . _temp_values . has_key ( k ) : <EOL> return True <EOL> else : <EOL> return ( k in self . _used_default ) == False <EOL> def has_unresolved_settings ( self ) : <EOL> return len ( self . _unresolved_values ) != <NUM_LIT:0> <EOL> def __getattr__ ( self , k ) : <EOL> if self . __dict__ . has_key ( k ) : <EOL> return self . __dict__ [ k ] <EOL> elif self . _temp_values . has_key ( k ) : <EOL> return self . _temp_values [ k ] <EOL> elif self . _values . has_key ( k ) : <EOL> return self . _values [ k ] <EOL> raise SettingDoesntExistException ( k ) <EOL> def __setattr__ ( self , k , v ) : <EOL> if self . __dict__ . has_key ( "<STR_LIT>" ) == False : <EOL> return object . __setattr__ ( self , k , v ) <EOL> elif self . __dict__ . has_key ( k ) : <EOL> return object . __setattr__ ( self , k , v ) <EOL> else : <EOL> if self . _types . has_key ( k ) == False : <EOL> raise SettingDoesntExistException ( k ) <EOL> if type ( v ) != self . _types [ k ] : <EOL> raise TypeError ( ) <EOL> changed = self . _values [ k ] != v <EOL> if changed : <EOL> old = self . _values [ k ] <EOL> self . _values [ k ] = v <EOL> if k in self . _used_default : <EOL> self . _used_default . remove ( k ) <EOL> self . _set_dirty ( ) <EOL> if changed and self . _change_fns [ k ] : <EOL> self . _change_fns [ k ] ( old , v ) <EOL> def __getitem__ ( self , k ) : <EOL> return self . __getattr__ ( k ) <EOL> def __setitem__ ( self , k , v ) : <EOL> return self . __setitem__ ( k , v ) <EOL> def set ( self , k , v ) : <EOL> self . __setattr__ ( k , v ) <EOL> def set_temporarily ( self , k , v ) : <EOL> if self . _types . has_key ( k ) == False : <EOL> raise SettingDoesntExistException ( k ) <EOL> if type ( v ) != self . _types [ k ] : <EOL> raise TypeError ( ) <EOL> self . _temp_values [ k ] = v <EOL> def unset_temporarily ( self , k , v ) : <EOL> if self . _temp_values . has_key ( k ) == False : <EOL> raise SettingDoesntExistException ( "<STR_LIT>" % k ) <EOL> del self . _temp_values [ k ] </s>
