#NEWLINE# def _validate_format( format , alternative ) : #NEWLINE# #INDENT# "Test format string `alternative` against `format`.  `format` can be the\n    msgid of a message and `alternative` one of the `msgstr`\\s.  The two\n    arguments are not interchangeable as `alternative` may contain less\n    placeholders if `format` uses named placeholders.\n\n    The behavior of this function is undefined if the string does not use\n    string formattings.\n\n    If the string formatting of `alternative` is compatible to `format` the\n    function returns `None`, otherwise a `TranslationError` is raised.\n\n    Examples for compatible format strings:\n\n    >>> _validate_format('Hello %s!', 'Hallo %s!')\n    >>> _validate_format('Hello %i!', 'Hallo %d!')\n\n    Example for an incompatible format strings:\n\n    >>> _validate_format('Hello %(name)s!', 'Hallo %s!')\n    Traceback (most recent call last):\n      ...\n    TranslationError: the format strings are of different kinds\n\n    This function is used by the `python_format` checker.\n\n    :param format: The original format string\n    :param alternative: The alternative format string that should be checked\n                        against format\n    :return: None on success\n    :raises TranslationError: on formatting errors\n    " #NEWLINE# def _parse( string ) : #NEWLINE# #INDENT# result = [ ] #NEWLINE# for match in PYTHON_FORMAT . finditer ( string ) : #NEWLINE# #INDENT# ( name , format , typechar ) = match . groups ( ) #NEWLINE# if ( ( typechar == '%' ) and ( name is None ) ) : #NEWLINE# #INDENT# continue #NEWLINE# #UNINDENT# result . append ( ( name , str ( typechar ) ) ) #NEWLINE# #UNINDENT# return result #NEWLINE# #UNINDENT# def _compatible( a , b ) : #NEWLINE# #INDENT# if ( a == b ) : #NEWLINE# #INDENT# return True #NEWLINE# #UNINDENT# for set in _string_format_compatibilities : #NEWLINE# #INDENT# if ( ( a in set ) and ( b in set ) ) : #NEWLINE# #INDENT# return True #NEWLINE# #UNINDENT# #UNINDENT# return False #NEWLINE# #UNINDENT# def _check_positional( results ) : #NEWLINE# #INDENT# positional = None #NEWLINE# for ( name , char ) in results : #NEWLINE# #INDENT# if ( positional is None ) : #NEWLINE# #INDENT# positional = ( name is None ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( ( name is None ) != positional ) : #NEWLINE# #INDENT# raise TranslationError ( 'format string mixes positional and named placeholders' ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# return bool ( positional ) #NEWLINE# #UNINDENT# ( a , b ) = map ( _parse , ( format , alternative ) ) #NEWLINE# ( a_positional , b_positional ) = map ( _check_positional , ( a , b ) ) #NEWLINE# if ( a_positional and ( not b_positional ) and ( not b ) ) : #NEWLINE# #INDENT# raise TranslationError ( 'placeholders are incompatible' ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( a_positional != b_positional ) : #NEWLINE# #INDENT# raise TranslationError ( 'the format strings are of different kinds' ) #NEWLINE# #UNINDENT# #UNINDENT# if a_positional : #NEWLINE# #INDENT# if ( len ( a ) != len ( b ) ) : #NEWLINE# #INDENT# raise TranslationError ( 'positional format placeholders are unbalanced' ) #NEWLINE# #UNINDENT# for ( idx , ( ( _ , first ) , ( _ , second ) ) ) in enumerate ( izip ( a , b ) ) : #NEWLINE# #INDENT# if ( not _compatible ( first , second ) ) : #NEWLINE# #INDENT# raise TranslationError ( ( 'incompatible format for placeholder %d: %r and %r are not compatible' % ( ( idx + 1 ) , first , second ) ) ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# type_map = dict ( a ) #NEWLINE# for ( name , typechar ) in b : #NEWLINE# #INDENT# if ( name not in type_map ) : #NEWLINE# #INDENT# raise TranslationError ( ( 'unknown named placeholder %r' % name ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( not _compatible ( typechar , type_map [ name ] ) ) : #NEWLINE# #INDENT# raise TranslationError ( ( 'incompatible format for placeholder %r: %r and %r are not compatible' % ( name , typechar , type_map [ name ] ) ) )