#NEWLINE# def read_po( fileobj , locale = None , domain = None , ignore_obsolete = False ) : #NEWLINE# #INDENT# 'Read messages from a ``gettext`` PO (portable object) file from the given\n    file-like object and return a `Catalog`.\n\n    >>> from StringIO import StringIO\n    >>> buf = StringIO(\'\'\'\n    ... #: main.py:1\n    ... #, fuzzy, python-format\n    ... msgid "foo %(name)s"\n    ... msgstr ""\n    ...\n    ... # A user comment\n    ... #. An auto comment\n    ... #: main.py:3\n    ... msgid "bar"\n    ... msgid_plural "baz"\n    ... msgstr[0] ""\n    ... msgstr[1] ""\n    ... \'\'\')\n    >>> catalog = read_po(buf)\n    >>> catalog.revision_date = datetime(2007, 04, 01)\n\n    >>> for message in catalog:\n    ...     if message.id:\n    ...         print (message.id, message.string)\n    ...         print \' \', (message.locations, message.flags)\n    ...         print \' \', (message.user_comments, message.auto_comments)\n    (u\'foo %(name)s\', \'\')\n      ([(u\'main.py\', 1)], set([u\'fuzzy\', u\'python-format\']))\n      ([], [])\n    ((u\'bar\', u\'baz\'), (\'\', \'\'))\n      ([(u\'main.py\', 3)], set([]))\n      ([u\'A user comment\'], [u\'An auto comment\'])\n\n    :param fileobj: the file-like object to read the PO file from\n    :param locale: the locale identifier or `Locale` object, or `None`\n                   if the catalog is not bound to a locale (which basically\n                   means it\'s a template)\n    :param domain: the message domain\n    :param ignore_obsolete: whether to ignore obsolete messages in the input\n    :return: a catalog object representing the parsed PO file\n    :rtype: `Catalog`\n    ' #NEWLINE# catalog = Catalog ( locale = locale , domain = domain ) #NEWLINE# counter = [ 0 ] #NEWLINE# offset = [ 0 ] #NEWLINE# messages = [ ] #NEWLINE# translations = [ ] #NEWLINE# locations = [ ] #NEWLINE# flags = [ ] #NEWLINE# user_comments = [ ] #NEWLINE# auto_comments = [ ] #NEWLINE# obsolete = [ False ] #NEWLINE# context = [ ] #NEWLINE# in_msgid = [ False ] #NEWLINE# in_msgstr = [ False ] #NEWLINE# in_msgctxt = [ False ] #NEWLINE# def _add_message( ) : #NEWLINE# #INDENT# translations . sort ( ) #NEWLINE# if ( len ( messages ) > 1 ) : #NEWLINE# #INDENT# msgid = tuple ( [ denormalize ( m ) for m in messages ] ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# msgid = denormalize ( messages [ 0 ] ) #NEWLINE# #UNINDENT# if isinstance ( msgid , ( list , tuple ) ) : #NEWLINE# #INDENT# string = [ ] #NEWLINE# for idx in range ( catalog . num_plurals ) : #NEWLINE# #INDENT# try : #NEWLINE# #INDENT# string . append ( translations [ idx ] ) #NEWLINE# #UNINDENT# except IndexError : #NEWLINE# #INDENT# string . append ( ( idx , '' ) ) #NEWLINE# #UNINDENT# #UNINDENT# string = tuple ( [ denormalize ( t [ 1 ] ) for t in string ] ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# string = denormalize ( translations [ 0 ] [ 1 ] ) #NEWLINE# #UNINDENT# if context : #NEWLINE# #INDENT# msgctxt = denormalize ( '\n' . join ( context ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# msgctxt = None #NEWLINE# #UNINDENT# message = Message ( msgid , string , list ( locations ) , set ( flags ) , auto_comments , user_comments , lineno = ( offset [ 0 ] + 1 ) , context = msgctxt ) #NEWLINE# if obsolete [ 0 ] : #NEWLINE# #INDENT# if ( not ignore_obsolete ) : #NEWLINE# #INDENT# catalog . obsolete [ msgid ] = message #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# catalog [ msgid ] = message #NEWLINE# #UNINDENT# del messages [ : ] #NEWLINE# del translations [ : ] #NEWLINE# del context [ : ] #NEWLINE# del locations [ : ] #NEWLINE# del flags [ : ] #NEWLINE# del auto_comments [ : ] #NEWLINE# del user_comments [ : ] #NEWLINE# obsolete [ 0 ] = False #NEWLINE# counter [ 0 ] += 1 #NEWLINE# #UNINDENT# def _process_message_line( lineno , line ) : #NEWLINE# #INDENT# if line . startswith ( 'msgid_plural' ) : #NEWLINE# #INDENT# in_msgid [ 0 ] = True #NEWLINE# msg = line [ 12 : ] . lstrip ( ) #NEWLINE# messages . append ( msg ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if line . startswith ( 'msgid' ) : #NEWLINE# #INDENT# in_msgid [ 0 ] = True #NEWLINE# offset [ 0 ] = lineno #NEWLINE# txt = line [ 5 : ] . lstrip ( ) #NEWLINE# if messages : #NEWLINE# #INDENT# _add_message ( ) #NEWLINE# #UNINDENT# messages . append ( txt ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if line . startswith ( 'msgstr' ) : #NEWLINE# #INDENT# in_msgid [ 0 ] = False #NEWLINE# in_msgstr [ 0 ] = True #NEWLINE# msg = line [ 6 : ] . lstrip ( ) #NEWLINE# if msg . startswith ( '[' ) : #NEWLINE# #INDENT# ( idx , msg ) = msg [ 1 : ] . split ( ']' ) #NEWLINE# translations . append ( [ int ( idx ) , msg . lstrip ( ) ] ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# translations . append ( [ 0 , msg ] ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if line . startswith ( 'msgctxt' ) : #NEWLINE# #INDENT# if messages : #NEWLINE# #INDENT# _add_message ( ) #NEWLINE# #UNINDENT# in_msgid [ 0 ] = in_msgstr [ 0 ] = False #NEWLINE# context . append ( line [ 7 : ] . lstrip ( ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if line . startswith ( '"' ) : #NEWLINE# #INDENT# if in_msgid [ 0 ] : #NEWLINE# #INDENT# messages [ ( - 1 ) ] += ( '\n' + line . rstrip ( ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if in_msgstr [ 0 ] : #NEWLINE# #INDENT# translations [ ( - 1 ) ] [ 1 ] += ( '\n' + line . rstrip ( ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if in_msgctxt [ 0 ] : #NEWLINE# #INDENT# context . append ( line . rstrip ( ) ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# for ( lineno , line ) in enumerate ( fileobj . readlines ( ) ) : #NEWLINE# #INDENT# line = line . strip ( ) #NEWLINE# if ( not isinstance ( offset , unicode ) ) : #NEWLINE# #INDENT# line = line . decode ( catalog . charset ) #NEWLINE# #UNINDENT# if line . startswith ( '#' ) : #NEWLINE# #INDENT# in_msgid [ 0 ] = in_msgstr [ 0 ] = False #NEWLINE# if ( messages and translations ) : #NEWLINE# #INDENT# _add_message ( ) #NEWLINE# #UNINDENT# if line [ 1 : ] . startswith ( ':' ) : #NEWLINE# #INDENT# for location in line [ 2 : ] . lstrip ( ) . split ( ) : #NEWLINE# #INDENT# pos = location . rfind ( ':' ) #NEWLINE# if ( pos >= 0 ) : #NEWLINE# #INDENT# try : #NEWLINE# #INDENT# lineno = int ( location [ ( pos + 1 ) : ] ) #NEWLINE# #UNINDENT# except ValueError : #NEWLINE# #INDENT# continue #NEWLINE# #UNINDENT# locations . append ( ( location [ : pos ] , lineno ) ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if line [ 1 : ] . startswith ( ',' ) : #NEWLINE# #INDENT# for flag in line [ 2 : ] . lstrip ( ) . split ( ',' ) : #NEWLINE# #INDENT# flags . append ( flag . strip ( ) ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if line [ 1 : ] . startswith ( '~' ) : #NEWLINE# #INDENT# obsolete [ 0 ] = True #NEWLINE# _process_message_line ( lineno , line [ 2 : ] . lstrip ( ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if line [ 1 : ] . startswith ( '.' ) : #NEWLINE# #INDENT# comment = line [ 2 : ] . strip ( ) #NEWLINE# if comment : #NEWLINE# #INDENT# auto_comments . append ( comment ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# user_comments . append ( line [ 1 : ] . strip ( ) ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# _process_message_line ( lineno , line ) #NEWLINE# #UNINDENT# #UNINDENT# if messages : #NEWLINE# #INDENT# _add_message ( ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( ( not counter [ 0 ] ) and ( flags or user_comments or auto_comments ) ) : #NEWLINE# #INDENT# messages . append ( '' ) #NEWLINE# translations . append ( [ 0 , '' ] ) #NEWLINE# _add_message ( ) #NEWLINE# #UNINDENT# #UNINDENT# return catalog