<s> from __future__ import print_function , absolute_import , unicode_literals <EOL> import yaml <EOL> import os <EOL> from contextlib import contextmanager <EOL> from chalmers import errors <EOL> class PersistentDict ( dict ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , filename , load = True ) : <EOL> self . _filename = os . path . abspath ( filename ) <EOL> if load : self . _load ( ) <EOL> self . _transact = False <EOL> @ property <EOL> def filename ( self ) : <EOL> '<STR_LIT>' <EOL> return self . _filename <EOL> def exists ( self ) : <EOL> '<STR_LIT>' <EOL> return os . path . exists ( self . _filename ) <EOL> def reload ( self ) : <EOL> '<STR_LIT>' <EOL> self . _load ( ) <EOL> self . _store ( ) <EOL> def delete ( self ) : <EOL> '<STR_LIT>' <EOL> if os . path . isfile ( self . _filename ) : <EOL> os . unlink ( self . _filename ) <EOL> def _load ( self ) : <EOL> '<STR_LIT>' <EOL> if os . path . isfile ( self . _filename ) : <EOL> with open ( self . _filename ) as fd : <EOL> dict . clear ( self ) <EOL> data = yaml . safe_load ( fd ) <EOL> if data : <EOL> dict . update ( self , data ) <EOL> def _store ( self ) : <EOL> '<STR_LIT>' <EOL> dir = os . path . dirname ( self . _filename ) <EOL> if dir and not os . path . isdir ( dir ) : <EOL> os . makedirs ( dir ) <EOL> with open ( self . _filename , '<STR_LIT:w>' ) as fd : <EOL> yaml . safe_dump ( dict ( self ) , fd ) <EOL> def _mk_lockfile ( self ) : <EOL> '<STR_LIT>' <EOL> lockfile = self . _filename + '<STR_LIT>' <EOL> try : <EOL> if self . exists ( ) : <EOL> os . link ( self . _filename , lockfile ) <EOL> else : <EOL> os . mkdir ( lockfile ) <EOL> except OSError as err : <EOL> if err . errno == <NUM_LIT> : <EOL> msg = ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" % ( self . _filename , lockfile ) ) <EOL> raise errors . ChalmersError ( msg ) <EOL> raise <EOL> def _rm_lockfile ( self ) : <EOL> '<STR_LIT>' <EOL> lockfile = self . _filename + '<STR_LIT>' <EOL> if os . path . isdir ( lockfile ) : <EOL> os . rmdir ( lockfile ) <EOL> elif os . path . isfile ( lockfile ) : <EOL> os . unlink ( lockfile ) <EOL> @ contextmanager <EOL> def file_lock ( self ) : <EOL> '<STR_LIT>' <EOL> transact = self . _transact <EOL> self . _transact = True <EOL> if not transact : <EOL> self . _mk_lockfile ( ) <EOL> try : <EOL> yield transact <EOL> finally : <EOL> if not transact : <EOL> self . _rm_lockfile ( ) <EOL> self . _transact = transact <EOL> @ contextmanager <EOL> def transaction ( self ) : <EOL> """<STR_LIT>""" <EOL> transact = self . _transact <EOL> self . _transact = True <EOL> if not transact : <EOL> self . _load ( ) <EOL> yield <EOL> if not transact : <EOL> self . _store ( ) <EOL> self . _transact = transact <EOL> def __setitem__ ( self , * args , ** kwargs ) : <EOL> with self . transaction ( ) : <EOL> return dict . __setitem__ ( self , * args , ** kwargs ) <EOL> def update ( self , * args , ** kwargs ) : <EOL> with self . transaction ( ) : <EOL> return dict . update ( self , * args , ** kwargs ) <EOL> def setdefault ( self , * args , ** kwargs ) : <EOL> with self . transaction ( ) : <EOL> return dict . setdefault ( self , * args , ** kwargs ) <EOL> def pop ( self , * args , ** kwargs ) : <EOL> with self . transaction ( ) : <EOL> return dict . pop ( self , * args , ** kwargs ) <EOL> def popitem ( self , * args , ** kwargs ) : <EOL> with self . transaction ( ) : <EOL> return dict . popitem ( self , * args , ** kwargs ) <EOL> def clear ( self ) : <EOL> with self . transaction ( ) : <EOL> return dict . clar ( self ) </s>
