<s> """<STR_LIT>""" <EOL> import re <EOL> import sys <EOL> if sys . version_info >= ( <NUM_LIT:3> , ) : <EOL> basestring = str <EOL> class PropertyListParseError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class XmlPropertyListParser ( object ) : <EOL> """<STR_LIT>""" <EOL> def _assert ( self , test , message ) : <EOL> if not test : <EOL> raise PropertyListParseError ( message ) <EOL> def setDocumentLocator ( self , locator ) : <EOL> pass <EOL> def startPrefixMapping ( self , prefix , uri ) : <EOL> pass <EOL> def endPrefixMapping ( self , prefix ) : <EOL> pass <EOL> def startElementNS ( self , name , qname , attrs ) : <EOL> pass <EOL> def endElementNS ( self , name , qname ) : <EOL> pass <EOL> def ignorableWhitespace ( self , whitespace ) : <EOL> pass <EOL> def processingInstruction ( self , target , data ) : <EOL> pass <EOL> def skippedEntity ( self , name ) : <EOL> pass <EOL> def startDocument ( self ) : <EOL> self . __stack = [ ] <EOL> self . __plist = self . __key = self . __characters = None <EOL> self . __in_dict = False <EOL> def endDocument ( self ) : <EOL> self . _assert ( self . __plist is not None , "<STR_LIT>" ) <EOL> self . _assert ( <EOL> len ( self . __stack ) is <NUM_LIT:0> , <EOL> "<STR_LIT>" ) <EOL> def startElement ( self , name , attributes ) : <EOL> if name in XmlPropertyListParser . START_CALLBACKS : <EOL> XmlPropertyListParser . START_CALLBACKS [ name ] ( self , name , attributes ) <EOL> if name in XmlPropertyListParser . PARSE_CALLBACKS : <EOL> self . __characters = [ ] <EOL> def endElement ( self , name ) : <EOL> if name in XmlPropertyListParser . END_CALLBACKS : <EOL> XmlPropertyListParser . END_CALLBACKS [ name ] ( self , name ) <EOL> if name in XmlPropertyListParser . PARSE_CALLBACKS : <EOL> content = '<STR_LIT>' . join ( self . __characters ) <EOL> try : <EOL> content = content . encode ( '<STR_LIT:ascii>' ) <EOL> except ( UnicodeError , AttributeError ) : <EOL> pass <EOL> XmlPropertyListParser . PARSE_CALLBACKS [ name ] ( self , name , content ) <EOL> self . __characters = None <EOL> def characters ( self , content ) : <EOL> if self . __characters is not None : <EOL> self . __characters . append ( content ) <EOL> def _push_value ( self , value ) : <EOL> if not self . __stack : <EOL> self . _assert ( self . __plist is None , "<STR_LIT>" ) <EOL> self . __plist = value <EOL> else : <EOL> top = self . __stack [ - <NUM_LIT:1> ] <EOL> if self . __in_dict : <EOL> k = self . __key <EOL> if k is None : <EOL> raise PropertyListParseError ( "<STR_LIT>" ) <EOL> top [ k ] = value <EOL> self . __key = None <EOL> else : <EOL> top . append ( value ) <EOL> def _push_stack ( self , value ) : <EOL> self . __stack . append ( value ) <EOL> self . __in_dict = isinstance ( value , dict ) <EOL> def _pop_stack ( self ) : <EOL> self . __stack . pop ( ) <EOL> self . __in_dict = self . __stack and isinstance ( self . __stack [ - <NUM_LIT:1> ] , dict ) <EOL> def _start_plist ( self , name , attrs ) : <EOL> self . _assert ( not self . __stack and self . __plist is None , "<STR_LIT>" ) <EOL> self . _assert ( attrs . get ( '<STR_LIT:version>' , '<STR_LIT:1.0>' ) == '<STR_LIT:1.0>' , <EOL> "<STR_LIT>" % attrs . get ( '<STR_LIT:version>' ) ) <EOL> def _start_array ( self , name , attrs ) : <EOL> v = list ( ) <EOL> self . _push_value ( v ) <EOL> self . _push_stack ( v ) <EOL> def _start_dict ( self , name , attrs ) : <EOL> v = dict ( ) <EOL> self . _push_value ( v ) <EOL> self . _push_stack ( v ) <EOL> def _end_array ( self , name ) : <EOL> self . _pop_stack ( ) <EOL> def _end_dict ( self , name ) : <EOL> if self . __key is not None : <EOL> raise PropertyListParseError ( "<STR_LIT>" % self . __key ) <EOL> self . _pop_stack ( ) <EOL> def _start_true ( self , name , attrs ) : <EOL> self . _push_value ( True ) <EOL> def _start_false ( self , name , attrs ) : <EOL> self . _push_value ( False ) <EOL> def _parse_key ( self , name , content ) : <EOL> if not self . __in_dict : <EOL> raise PropertyListParseError ( "<STR_LIT>" ) <EOL> self . __key = content <EOL> def _parse_string ( self , name , content ) : <EOL> self . _push_value ( content ) <EOL> def _parse_data ( self , name , content ) : <EOL> import base64 <EOL> self . _push_value ( base64 . b64decode ( content ) ) <EOL> DATETIME_PATTERN = re . compile ( r"<STR_LIT>" ) <EOL> def _parse_date ( self , name , content ) : <EOL> import datetime <EOL> units = ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , ) <EOL> pattern = XmlPropertyListParser . DATETIME_PATTERN <EOL> match = pattern . match ( content ) <EOL> if not match : <EOL> raise PropertyListParseError ( "<STR_LIT>" % content ) <EOL> groups , components = match . groupdict ( ) , [ ] <EOL> for key in units : <EOL> value = groups [ key ] <EOL> if value is None : <EOL> break <EOL> components . append ( int ( value ) ) <EOL> while len ( components ) < <NUM_LIT:3> : <EOL> components . append ( <NUM_LIT:1> ) <EOL> d = datetime . datetime ( * components ) <EOL> self . _push_value ( d ) <EOL> def _parse_real ( self , name , content ) : <EOL> self . _push_value ( float ( content ) ) <EOL> def _parse_integer ( self , name , content ) : <EOL> self . _push_value ( int ( content ) ) <EOL> START_CALLBACKS = { <EOL> '<STR_LIT>' : _start_plist , <EOL> '<STR_LIT>' : _start_array , <EOL> '<STR_LIT>' : _start_dict , <EOL> '<STR_LIT:true>' : _start_true , <EOL> '<STR_LIT:false>' : _start_false , <EOL> } <EOL> END_CALLBACKS = { <EOL> '<STR_LIT>' : _end_array , <EOL> '<STR_LIT>' : _end_dict , <EOL> } <EOL> PARSE_CALLBACKS = { <EOL> '<STR_LIT:key>' : _parse_key , <EOL> '<STR_LIT:string>' : _parse_string , <EOL> '<STR_LIT:data>' : _parse_data , <EOL> '<STR_LIT:date>' : _parse_date , <EOL> '<STR_LIT>' : _parse_real , <EOL> '<STR_LIT>' : _parse_integer , <EOL> } <EOL> def _to_stream ( self , io_or_string ) : <EOL> if isinstance ( io_or_string , basestring ) : <EOL> from cStringIO import StringIO <EOL> return StringIO ( io_or_string ) <EOL> elif hasattr ( io_or_string , '<STR_LIT>' ) and callable ( getattr ( io_or_string , '<STR_LIT>' ) ) : <EOL> return io_or_string <EOL> else : <EOL> raise TypeError ( '<STR_LIT>' % type ( io_or_string ) ) <EOL> def _parse_using_etree ( self , xml_input ) : <EOL> from xml . etree . cElementTree import iterparse <EOL> parser = iterparse ( self . _to_stream ( xml_input ) , events = ( '<STR_LIT:start>' , '<STR_LIT:end>' ) ) <EOL> self . startDocument ( ) <EOL> try : <EOL> for action , element in parser : <EOL> name = element . tag <EOL> if action == '<STR_LIT:start>' : <EOL> if name in XmlPropertyListParser . START_CALLBACKS : <EOL> XmlPropertyListParser . START_CALLBACKS [ name ] ( self , element . tag , element . attrib ) <EOL> elif action == '<STR_LIT:end>' : <EOL> if name in XmlPropertyListParser . END_CALLBACKS : <EOL> XmlPropertyListParser . END_CALLBACKS [ name ] ( self , name ) <EOL> if name in XmlPropertyListParser . PARSE_CALLBACKS : <EOL> XmlPropertyListParser . PARSE_CALLBACKS [ name ] ( self , name , element . text or "<STR_LIT>" ) <EOL> element . clear ( ) <EOL> except SyntaxError as e : <EOL> raise PropertyListParseError ( e ) <EOL> self . endDocument ( ) <EOL> return self . __plist <EOL> def _parse_using_sax_parser ( self , xml_input ) : <EOL> from xml . sax import make_parser , xmlreader , SAXParseException <EOL> source = xmlreader . InputSource ( ) <EOL> source . setByteStream ( self . _to_stream ( xml_input ) ) <EOL> reader = make_parser ( ) <EOL> reader . setContentHandler ( self ) <EOL> try : <EOL> reader . parse ( source ) <EOL> except SAXParseException as e : <EOL> raise PropertyListParseError ( e ) <EOL> return self . __plist <EOL> def parse ( self , xml_input ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> return self . _parse_using_etree ( xml_input ) <EOL> except ImportError : <EOL> return self . _parse_using_sax_parser ( xml_input ) <EOL> def parse_string ( io_or_string ) : <EOL> """<STR_LIT>""" <EOL> return XmlPropertyListParser ( ) . parse ( io_or_string ) <EOL> def parse_file ( file_path ) : <EOL> """<STR_LIT>""" <EOL> with open ( file_path ) as f : <EOL> return XmlPropertyListParser ( ) . parse ( f ) </s>
