<s> """<STR_LIT>""" <EOL> __author__ = "<STR_LIT>" <EOL> __status__ = "<STR_LIT>" <EOL> __version__ = "<STR_LIT>" <EOL> __date__ = "<STR_LIT>" <EOL> from types import StringType , UnicodeType <EOL> import codecs <EOL> import logging <EOL> import os <EOL> import sys <EOL> WORD = '<STR_LIT:a>' <EOL> NUMBER = '<STR_LIT>' <EOL> STRING = '<STR_LIT:">' <EOL> EOF = '<STR_LIT>' <EOL> LCURLY = '<STR_LIT:{>' <EOL> RCURLY = '<STR_LIT:}>' <EOL> LBRACK = '<STR_LIT:[>' <EOL> LBRACK2 = '<STR_LIT>' <EOL> RBRACK = '<STR_LIT:]>' <EOL> LPAREN = '<STR_LIT:(>' <EOL> LPAREN2 = '<STR_LIT>' <EOL> RPAREN = '<STR_LIT:)>' <EOL> DOT = '<STR_LIT:.>' <EOL> COMMA = '<STR_LIT:U+002C>' <EOL> COLON = '<STR_LIT::>' <EOL> AT = '<STR_LIT:@>' <EOL> PLUS = '<STR_LIT:+>' <EOL> MINUS = '<STR_LIT:->' <EOL> STAR = '<STR_LIT:*>' <EOL> SLASH = '<STR_LIT:/>' <EOL> MOD = '<STR_LIT:%>' <EOL> BACKTICK = '<STR_LIT>' <EOL> DOLLAR = '<STR_LIT:$>' <EOL> TRUE = '<STR_LIT:True>' <EOL> FALSE = '<STR_LIT:False>' <EOL> NONE = '<STR_LIT:None>' <EOL> WORDCHARS = "<STR_LIT>" <EOL> if sys . platform == '<STR_LIT:win32>' : <EOL> NEWLINE = '<STR_LIT:\r\n>' <EOL> elif os . name == '<STR_LIT>' : <EOL> NEWLINE = '<STR_LIT:\r>' <EOL> else : <EOL> NEWLINE = '<STR_LIT:\n>' <EOL> try : <EOL> import encodings . utf_32 <EOL> has_utf32 = True <EOL> except : <EOL> has_utf32 = False <EOL> try : <EOL> from logging . handlers import NullHandler <EOL> except ImportError : <EOL> class NullHandler ( logging . Handler ) : <EOL> def emit ( self , record ) : <EOL> pass <EOL> logger = logging . getLogger ( __name__ ) <EOL> if not logger . handlers : <EOL> logger . addHandler ( NullHandler ( ) ) <EOL> class ConfigInputStream ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , stream ) : <EOL> """<STR_LIT>""" <EOL> encoding = None <EOL> signature = stream . read ( <NUM_LIT:4> ) <EOL> used = - <NUM_LIT:1> <EOL> if has_utf32 : <EOL> if signature == codecs . BOM_UTF32_LE : <EOL> encoding = '<STR_LIT>' <EOL> elif signature == codecs . BOM_UTF32_BE : <EOL> encoding = '<STR_LIT>' <EOL> if encoding is None : <EOL> if signature [ : <NUM_LIT:3> ] == codecs . BOM_UTF8 : <EOL> used = <NUM_LIT:3> <EOL> encoding = '<STR_LIT:utf-8>' <EOL> elif signature [ : <NUM_LIT:2> ] == codecs . BOM_UTF16_LE : <EOL> used = <NUM_LIT:2> <EOL> encoding = '<STR_LIT>' <EOL> elif signature [ : <NUM_LIT:2> ] == codecs . BOM_UTF16_BE : <EOL> used = <NUM_LIT:2> <EOL> encoding = '<STR_LIT>' <EOL> else : <EOL> used = <NUM_LIT:0> <EOL> if used >= <NUM_LIT:0> : <EOL> stream . seek ( used ) <EOL> if encoding : <EOL> reader = codecs . getreader ( encoding ) <EOL> stream = reader ( stream ) <EOL> self . stream = stream <EOL> self . encoding = encoding <EOL> def read ( self , size ) : <EOL> if ( size == <NUM_LIT:0> ) or ( self . encoding is None ) : <EOL> rv = self . stream . read ( size ) <EOL> else : <EOL> rv = u'<STR_LIT>' <EOL> while size > <NUM_LIT:0> : <EOL> rv += self . stream . read ( <NUM_LIT:1> ) <EOL> size -= <NUM_LIT:1> <EOL> return rv <EOL> def close ( self ) : <EOL> self . stream . close ( ) <EOL> def readline ( self ) : <EOL> if self . encoding is None : <EOL> line = '<STR_LIT>' <EOL> else : <EOL> line = u'<STR_LIT>' <EOL> while True : <EOL> c = self . stream . read ( <NUM_LIT:1> ) <EOL> if c : <EOL> line += c <EOL> if c == '<STR_LIT:\n>' : <EOL> break <EOL> return line <EOL> class ConfigOutputStream ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , stream , encoding = None ) : <EOL> """<STR_LIT>""" <EOL> if encoding is not None : <EOL> encoding = str ( encoding ) . lower ( ) <EOL> self . encoding = encoding <EOL> if encoding == "<STR_LIT:utf-8>" : <EOL> stream . write ( codecs . BOM_UTF8 ) <EOL> elif encoding == "<STR_LIT>" : <EOL> stream . write ( codecs . BOM_UTF16_BE ) <EOL> elif encoding == "<STR_LIT>" : <EOL> stream . write ( codecs . BOM_UTF16_LE ) <EOL> elif encoding == "<STR_LIT>" : <EOL> stream . write ( codecs . BOM_UTF32_BE ) <EOL> elif encoding == "<STR_LIT>" : <EOL> stream . write ( codecs . BOM_UTF32_LE ) <EOL> if encoding is not None : <EOL> writer = codecs . getwriter ( encoding ) <EOL> stream = writer ( stream ) <EOL> self . stream = stream <EOL> def write ( self , data ) : <EOL> self . stream . write ( data ) <EOL> def flush ( self ) : <EOL> self . stream . flush ( ) <EOL> def close ( self ) : <EOL> self . stream . close ( ) <EOL> def defaultStreamOpener ( name ) : <EOL> """<STR_LIT>""" <EOL> return ConfigInputStream ( file ( name , '<STR_LIT:rb>' ) ) <EOL> streamOpener = None <EOL> class ConfigError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class ConfigFormatError ( ConfigError ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class ConfigResolutionError ( ConfigError ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def isWord ( s ) : <EOL> """<STR_LIT>""" <EOL> if type ( s ) != type ( '<STR_LIT>' ) : <EOL> return False <EOL> s = s . replace ( '<STR_LIT:_>' , '<STR_LIT>' ) <EOL> return s . isalnum ( ) <EOL> def makePath ( prefix , suffix ) : <EOL> """<STR_LIT>""" <EOL> if not prefix : <EOL> rv = suffix <EOL> elif suffix [ <NUM_LIT:0> ] == '<STR_LIT:[>' : <EOL> rv = prefix + suffix <EOL> else : <EOL> rv = prefix + '<STR_LIT:.>' + suffix <EOL> return rv <EOL> class Container ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , parent ) : <EOL> """<STR_LIT>""" <EOL> object . __setattr__ ( self , '<STR_LIT>' , parent ) <EOL> def setPath ( self , path ) : <EOL> """<STR_LIT>""" <EOL> object . __setattr__ ( self , '<STR_LIT:path>' , path ) <EOL> def evaluate ( self , item ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( item , Reference ) : <EOL> item = item . resolve ( self ) <EOL> elif isinstance ( item , Expression ) : <EOL> item = item . evaluate ( self ) <EOL> return item <EOL> def writeToStream ( self , stream , indent , container ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError <EOL> def writeValue ( self , value , stream , indent ) : <EOL> if isinstance ( self , Mapping ) : <EOL> indstr = '<STR_LIT:U+0020>' <EOL> else : <EOL> indstr = indent * '<STR_LIT:U+0020>' <EOL> if isinstance ( value , Reference ) or isinstance ( value , Expression ) : <EOL> stream . write ( '<STR_LIT>' % ( indstr , value , NEWLINE ) ) <EOL> else : <EOL> if ( type ( value ) is StringType ) : <EOL> value = repr ( value ) <EOL> stream . write ( '<STR_LIT>' % ( indstr , value , NEWLINE ) ) <EOL> class Mapping ( Container ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , parent = None ) : <EOL> """<STR_LIT>""" <EOL> Container . __init__ ( self , parent ) <EOL> object . __setattr__ ( self , '<STR_LIT:path>' , '<STR_LIT>' ) <EOL> object . __setattr__ ( self , '<STR_LIT:data>' , { } ) <EOL> object . __setattr__ ( self , '<STR_LIT>' , [ ] ) <EOL> object . __setattr__ ( self , '<STR_LIT>' , { } ) <EOL> def __delitem__ ( self , key ) : <EOL> """<STR_LIT>""" <EOL> data = object . __getattribute__ ( self , '<STR_LIT:data>' ) <EOL> if key not in data : <EOL> raise AttributeError ( key ) <EOL> order = object . __getattribute__ ( self , '<STR_LIT>' ) <EOL> comments = object . __getattribute__ ( self , '<STR_LIT>' ) <EOL> del data [ key ] <EOL> order . remove ( key ) <EOL> del comments [ key ] <EOL> def __getitem__ ( self , key ) : <EOL> data = object . __getattribute__ ( self , '<STR_LIT:data>' ) <EOL> if key not in data : <EOL> raise AttributeError ( key ) <EOL> rv = data [ key ] <EOL> return self . evaluate ( rv ) <EOL> __getattr__ = __getitem__ <EOL> def __getattribute__ ( self , name ) : <EOL> if name == "<STR_LIT>" : <EOL> return { } <EOL> if name in [ "<STR_LIT>" , "<STR_LIT>" ] : <EOL> return [ ] <EOL> data = object . __getattribute__ ( self , "<STR_LIT:data>" ) <EOL> useData = data . has_key ( name ) <EOL> if useData : <EOL> rv = getattr ( data , name ) <EOL> else : <EOL> rv = object . __getattribute__ ( self , name ) <EOL> if rv is None : <EOL> raise AttributeError ( name ) <EOL> return rv <EOL> def iteritems ( self ) : <EOL> for key in self . keys ( ) : <EOL> yield ( key , self [ key ] ) <EOL> raise StopIteration <EOL> def __contains__ ( self , item ) : <EOL> order = object . __getattribute__ ( self , '<STR_LIT>' ) <EOL> return item in order <EOL> def addMapping ( self , key , value , comment , setting = False ) : <EOL> """<STR_LIT>""" <EOL> data = object . __getattribute__ ( self , '<STR_LIT:data>' ) <EOL> order = object . __getattribute__ ( self , '<STR_LIT>' ) <EOL> comments = object . __getattribute__ ( self , '<STR_LIT>' ) <EOL> data [ key ] = value <EOL> if key not in order : <EOL> order . append ( key ) <EOL> elif not setting : <EOL> raise ConfigFormatError ( "<STR_LIT>" % key ) <EOL> comments [ key ] = comment <EOL> def __setattr__ ( self , name , value ) : <EOL> self . addMapping ( name , value , None , True ) <EOL> __setitem__ = __setattr__ <EOL> def keys ( self ) : <EOL> """<STR_LIT>""" <EOL> return object . __getattribute__ ( self , '<STR_LIT>' ) <EOL> def get ( self , key , default = None ) : <EOL> """<STR_LIT>""" <EOL> if key in self : <EOL> return self [ key ] <EOL> return default <EOL> def __str__ ( self ) : <EOL> return str ( object . __getattribute__ ( self , '<STR_LIT:data>' ) ) <EOL> def __repr__ ( self ) : <EOL> return repr ( object . __getattribute__ ( self , '<STR_LIT:data>' ) ) <EOL> def __len__ ( self ) : <EOL> return len ( object . __getattribute__ ( self , '<STR_LIT>' ) ) <EOL> def __iter__ ( self ) : <EOL> return self . iterkeys ( ) <EOL> def iterkeys ( self ) : <EOL> order = object . __getattribute__ ( self , '<STR_LIT>' ) <EOL> return order . __iter__ ( ) <EOL> def writeToStream ( self , stream , indent , container ) : <EOL> """<STR_LIT>""" <EOL> indstr = indent * '<STR_LIT:U+0020>' <EOL> if len ( self ) == <NUM_LIT:0> : <EOL> stream . write ( '<STR_LIT>' % NEWLINE ) <EOL> else : <EOL> if isinstance ( container , Mapping ) : <EOL> stream . write ( NEWLINE ) <EOL> stream . write ( '<STR_LIT>' % ( indstr , NEWLINE ) ) <EOL> self . save ( stream , indent + <NUM_LIT:1> ) <EOL> stream . write ( '<STR_LIT>' % ( indstr , NEWLINE ) ) <EOL> def save ( self , stream , indent = <NUM_LIT:0> ) : <EOL> """<STR_LIT>""" <EOL> indstr = indent * '<STR_LIT:U+0020>' <EOL> order = object . __getattribute__ ( self , '<STR_LIT>' ) <EOL> data = object . __getattribute__ ( self , '<STR_LIT:data>' ) <EOL> maxlen = <NUM_LIT:0> <EOL> for key in order : <EOL> comment = self . comments [ key ] <EOL> if isWord ( key ) : <EOL> skey = key <EOL> else : <EOL> skey = repr ( key ) <EOL> if comment : <EOL> stream . write ( '<STR_LIT>' % ( indstr , comment ) ) <EOL> stream . write ( '<STR_LIT>' % ( indstr , maxlen , skey ) ) <EOL> value = data [ key ] <EOL> if isinstance ( value , Container ) : <EOL> value . writeToStream ( stream , indent , self ) <EOL> else : <EOL> self . writeValue ( value , stream , indent ) <EOL> class Config ( Mapping ) : <EOL> """<STR_LIT>""" <EOL> class Namespace ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> self . sys = sys <EOL> self . os = os <EOL> def __repr__ ( self ) : <EOL> return "<STR_LIT>" % '<STR_LIT:U+002C>' . join ( self . __dict__ . keys ( ) ) <EOL> def __init__ ( self , streamOrFile = None , parent = None ) : <EOL> """<STR_LIT>""" <EOL> Mapping . __init__ ( self , parent ) <EOL> object . __setattr__ ( self , '<STR_LIT>' , ConfigReader ( self ) ) <EOL> object . __setattr__ ( self , '<STR_LIT>' , [ Config . Namespace ( ) ] ) <EOL> object . __setattr__ ( self , '<STR_LIT>' , set ( ) ) <EOL> if streamOrFile is not None : <EOL> if isinstance ( streamOrFile , StringType ) or isinstance ( streamOrFile , UnicodeType ) : <EOL> global streamOpener <EOL> if streamOpener is None : <EOL> streamOpener = defaultStreamOpener <EOL> streamOrFile = streamOpener ( streamOrFile ) <EOL> load = object . __getattribute__ ( self , "<STR_LIT>" ) <EOL> load ( streamOrFile ) <EOL> def load ( self , stream ) : <EOL> """<STR_LIT>""" <EOL> reader = object . __getattribute__ ( self , '<STR_LIT>' ) <EOL> reader . load ( stream ) <EOL> stream . close ( ) <EOL> def addNamespace ( self , ns , name = None ) : <EOL> """<STR_LIT>""" <EOL> namespaces = object . __getattribute__ ( self , '<STR_LIT>' ) <EOL> if name is None : <EOL> namespaces . append ( ns ) <EOL> else : <EOL> setattr ( namespaces [ <NUM_LIT:0> ] , name , ns ) <EOL> def removeNamespace ( self , ns , name = None ) : <EOL> """<STR_LIT>""" <EOL> namespaces = object . __getattribute__ ( self , '<STR_LIT>' ) <EOL> if name is None : <EOL> namespaces . remove ( ns ) <EOL> else : <EOL> delattr ( namespaces [ <NUM_LIT:0> ] , name ) <EOL> def save ( self , stream , indent = <NUM_LIT:0> ) : <EOL> """<STR_LIT>""" <EOL> Mapping . save ( self , stream , indent ) <EOL> if indent == <NUM_LIT:0> : <EOL> stream . close ( ) <EOL> def getByPath ( self , path ) : <EOL> """<STR_LIT>""" <EOL> s = '<STR_LIT>' + path <EOL> try : <EOL> return eval ( s ) <EOL> except Exception , e : <EOL> raise ConfigError ( str ( e ) ) <EOL> class Sequence ( Container ) : <EOL> """<STR_LIT>""" <EOL> class SeqIter ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , seq ) : <EOL> self . seq = seq <EOL> self . limit = len ( object . __getattribute__ ( seq , '<STR_LIT:data>' ) ) <EOL> self . index = <NUM_LIT:0> <EOL> def __iter__ ( self ) : <EOL> return self <EOL> def next ( self ) : <EOL> if self . index >= self . limit : <EOL> raise StopIteration <EOL> rv = self . seq [ self . index ] <EOL> self . index += <NUM_LIT:1> <EOL> return rv <EOL> def __init__ ( self , parent = None ) : <EOL> """<STR_LIT>""" <EOL> Container . __init__ ( self , parent ) <EOL> object . __setattr__ ( self , '<STR_LIT:data>' , [ ] ) <EOL> object . __setattr__ ( self , '<STR_LIT>' , [ ] ) <EOL> def append ( self , item , comment ) : <EOL> """<STR_LIT>""" <EOL> data = object . __getattribute__ ( self , '<STR_LIT:data>' ) <EOL> comments = object . __getattribute__ ( self , '<STR_LIT>' ) <EOL> data . append ( item ) <EOL> comments . append ( comment ) <EOL> def __getitem__ ( self , index ) : <EOL> data = object . __getattribute__ ( self , '<STR_LIT:data>' ) <EOL> try : <EOL> rv = data [ index ] <EOL> except ( IndexError , KeyError , TypeError ) : <EOL> raise ConfigResolutionError ( '<STR_LIT>' % ( index , object . __getattribute__ ( self , '<STR_LIT:path>' ) ) ) <EOL> if not isinstance ( rv , list ) : <EOL> rv = self . evaluate ( rv ) <EOL> else : <EOL> result = [ ] <EOL> for a in rv : <EOL> result . append ( self . evaluate ( a ) ) <EOL> rv = result <EOL> return rv <EOL> def __iter__ ( self ) : <EOL> return Sequence . SeqIter ( self ) <EOL> def __repr__ ( self ) : <EOL> return repr ( object . __getattribute__ ( self , '<STR_LIT:data>' ) ) <EOL> def __str__ ( self ) : <EOL> return str ( self [ : ] ) <EOL> def __len__ ( self ) : <EOL> return len ( object . __getattribute__ ( self , '<STR_LIT:data>' ) ) <EOL> def writeToStream ( self , stream , indent , container ) : <EOL> """<STR_LIT>""" <EOL> indstr = indent * '<STR_LIT:U+0020>' <EOL> if len ( self ) == <NUM_LIT:0> : <EOL> stream . write ( '<STR_LIT>' % NEWLINE ) <EOL> else : <EOL> if isinstance ( container , Mapping ) : <EOL> stream . write ( NEWLINE ) <EOL> stream . write ( '<STR_LIT>' % ( indstr , NEWLINE ) ) <EOL> self . save ( stream , indent + <NUM_LIT:1> ) <EOL> stream . write ( '<STR_LIT>' % ( indstr , NEWLINE ) ) <EOL> def save ( self , stream , indent ) : <EOL> """<STR_LIT>""" <EOL> if indent == <NUM_LIT:0> : <EOL> raise ConfigError ( "<STR_LIT>" ) <EOL> data = object . __getattribute__ ( self , '<STR_LIT:data>' ) <EOL> comments = object . __getattribute__ ( self , '<STR_LIT>' ) <EOL> indstr = indent * '<STR_LIT:U+0020>' <EOL> for i in xrange ( <NUM_LIT:0> , len ( data ) ) : <EOL> value = data [ i ] <EOL> comment = comments [ i ] <EOL> if comment : <EOL> stream . write ( '<STR_LIT>' % ( indstr , comment ) ) <EOL> if isinstance ( value , Container ) : <EOL> value . writeToStream ( stream , indent , self ) <EOL> else : <EOL> self . writeValue ( value , stream , indent ) <EOL> class Reference ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , config , type , ident ) : <EOL> """<STR_LIT>""" <EOL> self . config = config <EOL> self . type = type <EOL> self . elements = [ ident ] <EOL> def addElement ( self , type , ident ) : <EOL> """<STR_LIT>""" <EOL> self . elements . append ( ( type , ident ) ) <EOL> def findConfig ( self , container ) : <EOL> """<STR_LIT>""" <EOL> while ( container is not None ) and not isinstance ( container , Config ) : <EOL> container = object . __getattribute__ ( container , '<STR_LIT>' ) <EOL> return container <EOL> def resolve ( self , container ) : <EOL> """<STR_LIT>""" <EOL> rv = None <EOL> path = object . __getattribute__ ( container , '<STR_LIT:path>' ) <EOL> current = self . findConfig ( container ) <EOL> while current is not None : <EOL> if self . type == BACKTICK : <EOL> namespaces = object . __getattribute__ ( current , '<STR_LIT>' ) <EOL> found = False <EOL> s = str ( self ) [ <NUM_LIT:1> : - <NUM_LIT:1> ] <EOL> for ns in namespaces : <EOL> try : <EOL> try : <EOL> rv = eval ( s , vars ( ns ) ) <EOL> except TypeError : <EOL> rv = eval ( s , { } , vars ( ns ) ) <EOL> found = True <EOL> break <EOL> except : <EOL> logger . debug ( "<STR_LIT>" , s , ns ) <EOL> pass <EOL> if found : <EOL> break <EOL> else : <EOL> firstkey = self . elements [ <NUM_LIT:0> ] <EOL> if firstkey in current . resolving : <EOL> current . resolving . remove ( firstkey ) <EOL> raise ConfigResolutionError ( "<STR_LIT>" % firstkey ) <EOL> current . resolving . add ( firstkey ) <EOL> key = firstkey <EOL> try : <EOL> rv = current [ key ] <EOL> for item in self . elements [ <NUM_LIT:1> : ] : <EOL> key = item [ <NUM_LIT:1> ] <EOL> rv = rv [ key ] <EOL> current . resolving . remove ( firstkey ) <EOL> break <EOL> except ConfigResolutionError : <EOL> raise <EOL> except : <EOL> logger . debug ( "<STR_LIT>" , key , sys . exc_info ( ) [ <NUM_LIT:1> ] ) <EOL> rv = None <EOL> pass <EOL> current . resolving . discard ( firstkey ) <EOL> current = self . findConfig ( object . __getattribute__ ( current , '<STR_LIT>' ) ) <EOL> if current is None : <EOL> raise ConfigResolutionError ( "<STR_LIT>" % ( self , path ) ) <EOL> return rv <EOL> def __str__ ( self ) : <EOL> s = self . elements [ <NUM_LIT:0> ] <EOL> for tt , tv in self . elements [ <NUM_LIT:1> : ] : <EOL> if tt == DOT : <EOL> s += '<STR_LIT>' % tv <EOL> else : <EOL> s += '<STR_LIT>' % tv <EOL> if self . type == BACKTICK : <EOL> return BACKTICK + s + BACKTICK <EOL> else : <EOL> return DOLLAR + s <EOL> def __repr__ ( self ) : <EOL> return self . __str__ ( ) <EOL> class Expression ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , op , lhs , rhs ) : <EOL> """<STR_LIT>""" <EOL> self . op = op <EOL> self . lhs = lhs <EOL> self . rhs = rhs <EOL> def __str__ ( self ) : <EOL> return '<STR_LIT>' % ( self . lhs , self . op , self . rhs ) <EOL> def __repr__ ( self ) : <EOL> return self . __str__ ( ) <EOL> def evaluate ( self , container ) : <EOL> """<STR_LIT>""" <EOL> lhs = self . lhs <EOL> if isinstance ( lhs , Reference ) : <EOL> lhs = lhs . resolve ( container ) <EOL> elif isinstance ( lhs , Expression ) : <EOL> lhs = lhs . evaluate ( container ) <EOL> rhs = self . rhs <EOL> if isinstance ( rhs , Reference ) : <EOL> rhs = rhs . resolve ( container ) <EOL> elif isinstance ( rhs , Expression ) : <EOL> rhs = rhs . evaluate ( container ) <EOL> op = self . op <EOL> if op == PLUS : <EOL> rv = lhs + rhs <EOL> elif op == MINUS : <EOL> rv = lhs - rhs <EOL> elif op == STAR : <EOL> rv = lhs * rhs <EOL> elif op == SLASH : <EOL> rv = lhs / rhs <EOL> else : <EOL> rv = lhs % rhs <EOL> return rv <EOL> class ConfigReader ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , config ) : <EOL> self . filename = None <EOL> self . config = config <EOL> self . lineno = <NUM_LIT:0> <EOL> self . colno = <NUM_LIT:0> <EOL> self . lastc = None <EOL> self . last_token = None <EOL> self . commentchars = '<STR_LIT:#>' <EOL> self . whitespace = '<STR_LIT>' <EOL> self . quotes = '<STR_LIT>' <EOL> self . punct = '<STR_LIT>' <EOL> self . digits = '<STR_LIT>' <EOL> self . wordchars = '<STR_LIT:%s>' % WORDCHARS <EOL> self . identchars = self . wordchars + self . digits <EOL> self . pbchars = [ ] <EOL> self . pbtokens = [ ] <EOL> self . comment = None <EOL> def location ( self ) : <EOL> """<STR_LIT>""" <EOL> return "<STR_LIT>" % ( self . filename , self . lineno , self . colno ) <EOL> def getChar ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . pbchars : <EOL> c = self . pbchars . pop ( ) <EOL> else : <EOL> c = self . stream . read ( <NUM_LIT:1> ) <EOL> self . colno += <NUM_LIT:1> <EOL> if c == '<STR_LIT:\n>' : <EOL> self . lineno += <NUM_LIT:1> <EOL> self . colno = <NUM_LIT:1> <EOL> return c <EOL> def __repr__ ( self ) : <EOL> return "<STR_LIT>" % id ( self ) <EOL> __str__ = __repr__ <EOL> def getToken ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . pbtokens : <EOL> return self . pbtokens . pop ( ) <EOL> stream = self . stream <EOL> self . comment = None <EOL> token = '<STR_LIT>' <EOL> tt = EOF <EOL> while True : <EOL> c = self . getChar ( ) <EOL> if not c : <EOL> break <EOL> elif c == '<STR_LIT:#>' : <EOL> self . comment = stream . readline ( ) <EOL> self . lineno += <NUM_LIT:1> <EOL> continue <EOL> if c in self . quotes : <EOL> token = c <EOL> quote = c <EOL> tt = STRING <EOL> escaped = False <EOL> multiline = False <EOL> c1 = self . getChar ( ) <EOL> if c1 == quote : <EOL> c2 = self . getChar ( ) <EOL> if c2 == quote : <EOL> multiline = True <EOL> token += quote <EOL> token += quote <EOL> else : <EOL> self . pbchars . append ( c2 ) <EOL> self . pbchars . append ( c1 ) <EOL> else : <EOL> self . pbchars . append ( c1 ) <EOL> while True : <EOL> c = self . getChar ( ) <EOL> if not c : <EOL> break <EOL> token += c <EOL> if ( c == quote ) and not escaped : <EOL> if not multiline or ( len ( token ) >= <NUM_LIT:6> and token . endswith ( token [ : <NUM_LIT:3> ] ) and token [ - <NUM_LIT:4> ] != '<STR_LIT:\\>' ) : <EOL> break <EOL> if c == '<STR_LIT:\\>' : <EOL> escaped = not escaped <EOL> else : <EOL> escaped = False <EOL> if not c : <EOL> raise ConfigFormatError ( '<STR_LIT>' % ( self . location ( ) , token , c ) ) <EOL> break <EOL> if c in self . whitespace : <EOL> self . lastc = c <EOL> continue <EOL> elif c in self . punct : <EOL> token = c <EOL> tt = c <EOL> if ( self . lastc == '<STR_LIT:]>' ) or ( self . lastc in self . identchars ) : <EOL> if c == '<STR_LIT:[>' : <EOL> tt = LBRACK2 <EOL> elif c == '<STR_LIT:(>' : <EOL> tt = LPAREN2 <EOL> break <EOL> elif c in self . digits : <EOL> token = c <EOL> tt = NUMBER <EOL> in_exponent = False <EOL> while True : <EOL> c = self . getChar ( ) <EOL> if not c : <EOL> break <EOL> if c in self . digits : <EOL> token += c <EOL> elif ( c == '<STR_LIT:.>' ) and token . find ( '<STR_LIT:.>' ) < <NUM_LIT:0> and not in_exponent : <EOL> token += c <EOL> elif ( c == '<STR_LIT:->' ) and token . find ( '<STR_LIT:->' ) < <NUM_LIT:0> and in_exponent : <EOL> token += c <EOL> elif ( c in '<STR_LIT>' ) and token . find ( '<STR_LIT:e>' ) < <NUM_LIT:0> and token . find ( '<STR_LIT:E>' ) < <NUM_LIT:0> : <EOL> token += c <EOL> in_exponent = True <EOL> else : <EOL> if c and ( c not in self . whitespace ) : <EOL> self . pbchars . append ( c ) <EOL> break <EOL> break <EOL> elif c in self . wordchars : <EOL> token = c <EOL> tt = WORD <EOL> c = self . getChar ( ) <EOL> while c and ( c in self . identchars ) : <EOL> token += c <EOL> c = self . getChar ( ) <EOL> if c : <EOL> self . pbchars . append ( c ) <EOL> if token == "<STR_LIT:True>" : <EOL> tt = TRUE <EOL> elif token == "<STR_LIT:False>" : <EOL> tt = FALSE <EOL> elif token == "<STR_LIT:None>" : <EOL> tt = NONE <EOL> break <EOL> else : <EOL> raise ConfigFormatError ( '<STR_LIT>' % ( self . location ( ) , c ) ) <EOL> if token : <EOL> self . lastc = token [ - <NUM_LIT:1> ] <EOL> else : <EOL> self . lastc = None <EOL> self . last_token = tt <EOL> return ( tt , token ) <EOL> def load ( self , stream , parent = None , suffix = None ) : <EOL> """<STR_LIT>""" <EOL> if parent is not None : <EOL> if suffix is None : <EOL> raise ConfigError ( "<STR_LIT>" ) <EOL> self . config . setPath ( makePath ( object . __getattribute__ ( parent , '<STR_LIT:path>' ) , suffix ) ) <EOL> self . setStream ( stream ) <EOL> self . token = self . getToken ( ) <EOL> self . parseMappingBody ( self . config ) <EOL> if self . token [ <NUM_LIT:0> ] != EOF : <EOL> raise ConfigFormatError ( '<STR_LIT>' % ( self . location ( ) , self . token [ <NUM_LIT:1> ] ) ) <EOL> def setStream ( self , stream ) : <EOL> """<STR_LIT>""" <EOL> self . stream = stream <EOL> if hasattr ( stream , '<STR_LIT:name>' ) : <EOL> filename = stream . name <EOL> else : <EOL> filename = '<STR_LIT:?>' <EOL> self . filename = filename <EOL> self . lineno = <NUM_LIT:1> <EOL> self . colno = <NUM_LIT:1> <EOL> def match ( self , t ) : <EOL> """<STR_LIT>""" <EOL> if self . token [ <NUM_LIT:0> ] != t : <EOL> raise ConfigFormatError ( "<STR_LIT>" % ( self . location ( ) , t , self . token [ <NUM_LIT:1> ] ) ) <EOL> rv = self . token <EOL> self . token = self . getToken ( ) <EOL> return rv <EOL> def parseMappingBody ( self , parent ) : <EOL> """<STR_LIT>""" <EOL> while self . token [ <NUM_LIT:0> ] in [ WORD , STRING ] : <EOL> self . parseKeyValuePair ( parent ) <EOL> def parseKeyValuePair ( self , parent ) : <EOL> """<STR_LIT>""" <EOL> comment = self . comment <EOL> tt , tv = self . token <EOL> if tt == WORD : <EOL> key = tv <EOL> suffix = tv <EOL> elif tt == STRING : <EOL> key = eval ( tv ) <EOL> suffix = '<STR_LIT>' % tv <EOL> else : <EOL> msg = "<STR_LIT>" <EOL> raise ConfigFormatError ( msg % ( self . location ( ) , tv ) ) <EOL> self . token = self . getToken ( ) <EOL> if self . token [ <NUM_LIT:0> ] == COLON : <EOL> self . token = self . getToken ( ) <EOL> value = self . parseValue ( parent , suffix ) <EOL> else : <EOL> value = True <EOL> try : <EOL> parent . addMapping ( key , value , comment ) <EOL> except Exception , e : <EOL> raise ConfigFormatError ( "<STR_LIT>" % ( self . location ( ) , e , <EOL> self . token [ <NUM_LIT:1> ] ) ) <EOL> tt = self . token [ <NUM_LIT:0> ] <EOL> if tt not in [ EOF , WORD , STRING , RCURLY , COMMA ] : <EOL> msg = "<STR_LIT>" <EOL> raise ConfigFormatError ( msg % ( self . location ( ) , self . token [ <NUM_LIT:1> ] ) ) <EOL> if tt == COMMA : <EOL> self . token = self . getToken ( ) <EOL> def parseValue ( self , parent , suffix ) : <EOL> """<STR_LIT>""" <EOL> tt = self . token [ <NUM_LIT:0> ] <EOL> if tt in [ STRING , WORD , NUMBER , LPAREN , DOLLAR , <EOL> TRUE , FALSE , NONE , BACKTICK , MINUS ] : <EOL> rv = self . parseScalar ( ) <EOL> elif tt == LBRACK : <EOL> rv = self . parseSequence ( parent , suffix ) <EOL> elif tt in [ LCURLY , AT ] : <EOL> rv = self . parseMapping ( parent , suffix ) <EOL> else : <EOL> raise ConfigFormatError ( "<STR_LIT>" % <EOL> ( self . location ( ) , self . token [ <NUM_LIT:1> ] ) ) <EOL> return rv <EOL> def parseSequence ( self , parent , suffix ) : <EOL> """<STR_LIT>""" <EOL> rv = Sequence ( parent ) <EOL> rv . setPath ( makePath ( object . __getattribute__ ( parent , '<STR_LIT:path>' ) , suffix ) ) <EOL> self . match ( LBRACK ) <EOL> comment = self . comment <EOL> tt = self . token [ <NUM_LIT:0> ] <EOL> while tt in [ STRING , WORD , NUMBER , LCURLY , LBRACK , LPAREN , DOLLAR , <EOL> TRUE , FALSE , NONE , BACKTICK , MINUS ] : <EOL> suffix = '<STR_LIT>' % len ( rv ) <EOL> value = self . parseValue ( parent , suffix ) <EOL> rv . append ( value , comment ) <EOL> tt = self . token [ <NUM_LIT:0> ] <EOL> comment = self . comment <EOL> if tt == COMMA : <EOL> self . match ( COMMA ) <EOL> tt = self . token [ <NUM_LIT:0> ] <EOL> comment = self . comment <EOL> continue <EOL> self . match ( RBRACK ) <EOL> return rv <EOL> def parseMapping ( self , parent , suffix ) : <EOL> """<STR_LIT>""" <EOL> if self . token [ <NUM_LIT:0> ] == LCURLY : <EOL> self . match ( LCURLY ) <EOL> rv = Mapping ( parent ) <EOL> rv . setPath ( <EOL> makePath ( object . __getattribute__ ( parent , '<STR_LIT:path>' ) , suffix ) ) <EOL> self . parseMappingBody ( rv ) <EOL> self . match ( RCURLY ) <EOL> else : <EOL> self . match ( AT ) <EOL> tt , fn = self . match ( STRING ) <EOL> rv = Config ( eval ( fn ) , parent ) <EOL> return rv <EOL> def parseScalar ( self ) : <EOL> """<STR_LIT>""" <EOL> lhs = self . parseTerm ( ) <EOL> tt = self . token [ <NUM_LIT:0> ] <EOL> while tt in [ PLUS , MINUS ] : <EOL> self . match ( tt ) <EOL> rhs = self . parseTerm ( ) <EOL> lhs = Expression ( tt , lhs , rhs ) <EOL> tt = self . token [ <NUM_LIT:0> ] <EOL> return lhs <EOL> def parseTerm ( self ) : <EOL> """<STR_LIT>""" <EOL> lhs = self . parseFactor ( ) <EOL> tt = self . token [ <NUM_LIT:0> ] <EOL> while tt in [ STAR , SLASH , MOD ] : <EOL> self . match ( tt ) <EOL> rhs = self . parseFactor ( ) <EOL> lhs = Expression ( tt , lhs , rhs ) <EOL> tt = self . token [ <NUM_LIT:0> ] <EOL> return lhs <EOL> def parseFactor ( self ) : <EOL> """<STR_LIT>""" <EOL> tt = self . token [ <NUM_LIT:0> ] <EOL> if tt in [ NUMBER , WORD , STRING , TRUE , FALSE , NONE ] : <EOL> rv = self . token [ <NUM_LIT:1> ] <EOL> if tt != WORD : <EOL> rv = eval ( rv ) <EOL> self . match ( tt ) <EOL> elif tt == LPAREN : <EOL> self . match ( LPAREN ) <EOL> rv = self . parseScalar ( ) <EOL> self . match ( RPAREN ) <EOL> elif tt == DOLLAR : <EOL> self . match ( DOLLAR ) <EOL> rv = self . parseReference ( DOLLAR ) <EOL> elif tt == BACKTICK : <EOL> self . match ( BACKTICK ) <EOL> rv = self . parseReference ( BACKTICK ) <EOL> self . match ( BACKTICK ) <EOL> elif tt == MINUS : <EOL> self . match ( MINUS ) <EOL> rv = - self . parseScalar ( ) <EOL> else : <EOL> raise ConfigFormatError ( "<STR_LIT>" % <EOL> ( self . location ( ) , self . token [ <NUM_LIT:1> ] ) ) <EOL> return rv <EOL> def parseReference ( self , type ) : <EOL> """<STR_LIT>""" <EOL> word = self . match ( WORD ) <EOL> rv = Reference ( self . config , type , word [ <NUM_LIT:1> ] ) <EOL> while self . token [ <NUM_LIT:0> ] in [ DOT , LBRACK2 ] : <EOL> self . parseSuffix ( rv ) <EOL> return rv <EOL> def parseSuffix ( self , ref ) : <EOL> """<STR_LIT>""" <EOL> tt = self . token [ <NUM_LIT:0> ] <EOL> if tt == DOT : <EOL> self . match ( DOT ) <EOL> word = self . match ( WORD ) <EOL> ref . addElement ( DOT , word [ <NUM_LIT:1> ] ) <EOL> else : <EOL> self . match ( LBRACK2 ) <EOL> tt , tv = self . token <EOL> if tt not in [ NUMBER , STRING ] : <EOL> raise ConfigFormatError ( "<STR_LIT>" % ( self . location ( ) , tv ) ) <EOL> self . token = self . getToken ( ) <EOL> tv = eval ( tv ) <EOL> self . match ( RBRACK ) <EOL> ref . addElement ( LBRACK , tv ) <EOL> def defaultMergeResolve ( map1 , map2 , key ) : <EOL> """<STR_LIT>""" <EOL> obj1 = map1 [ key ] <EOL> obj2 = map2 [ key ] <EOL> if isinstance ( obj1 , Mapping ) and isinstance ( obj2 , Mapping ) : <EOL> rv = "<STR_LIT>" <EOL> elif isinstance ( obj1 , Sequence ) and isinstance ( obj2 , Sequence ) : <EOL> rv = "<STR_LIT>" <EOL> else : <EOL> rv = "<STR_LIT>" <EOL> return rv <EOL> def overwriteMergeResolve ( map1 , map2 , key ) : <EOL> """<STR_LIT>""" <EOL> rv = defaultMergeResolve ( map1 , map2 , key ) <EOL> if rv == "<STR_LIT>" : <EOL> rv = "<STR_LIT>" <EOL> return rv <EOL> class ConfigMerger ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , resolver = defaultMergeResolve ) : <EOL> """<STR_LIT>""" <EOL> self . resolver = resolver <EOL> def merge ( self , merged , mergee ) : <EOL> """<STR_LIT>""" <EOL> self . mergeMapping ( merged , mergee ) <EOL> def mergeMapping ( self , map1 , map2 ) : <EOL> """<STR_LIT>""" <EOL> keys = map1 . keys ( ) <EOL> for key in map2 . keys ( ) : <EOL> if key not in keys : <EOL> map1 [ key ] = map2 [ key ] <EOL> else : <EOL> obj1 = map1 [ key ] <EOL> obj2 = map2 [ key ] <EOL> decision = self . resolver ( map1 , map2 , key ) <EOL> if decision == "<STR_LIT>" : <EOL> self . mergeMapping ( obj1 , obj2 ) <EOL> elif decision == "<STR_LIT>" : <EOL> self . mergeSequence ( obj1 , obj2 ) <EOL> elif decision == "<STR_LIT>" : <EOL> map1 [ key ] = obj2 <EOL> elif decision == "<STR_LIT>" : <EOL> self . handleMismatch ( obj1 , obj2 ) <EOL> else : <EOL> msg = "<STR_LIT>" <EOL> raise ValueError ( msg % decision ) <EOL> def mergeSequence ( self , seq1 , seq2 ) : <EOL> """<STR_LIT>""" <EOL> data1 = object . __getattribute__ ( seq1 , '<STR_LIT:data>' ) <EOL> data2 = object . __getattribute__ ( seq2 , '<STR_LIT:data>' ) <EOL> for obj in data2 : <EOL> data1 . append ( obj ) <EOL> comment1 = object . __getattribute__ ( seq1 , '<STR_LIT>' ) <EOL> comment2 = object . __getattribute__ ( seq2 , '<STR_LIT>' ) <EOL> for obj in comment2 : <EOL> comment1 . append ( obj ) <EOL> def handleMismatch ( self , obj1 , obj2 ) : <EOL> """<STR_LIT>""" <EOL> raise ConfigError ( "<STR_LIT>" % ( obj1 , obj2 ) ) <EOL> class ConfigList ( list ) : <EOL> """<STR_LIT>""" <EOL> def getByPath ( self , path ) : <EOL> """<STR_LIT>""" <EOL> found = False <EOL> rv = None <EOL> for entry in self : <EOL> try : <EOL> rv = entry . getByPath ( path ) <EOL> found = True <EOL> break <EOL> except ConfigError : <EOL> pass <EOL> if not found : <EOL> raise ConfigError ( "<STR_LIT>" % path ) <EOL> return rv </s>
