<s> """<STR_LIT>""" <EOL> from collections import deque <EOL> from jinja2 import nodes <EOL> from jinja2 . defaults import * <EOL> from jinja2 . environment import get_spontaneous_environment <EOL> from jinja2 . runtime import Undefined , concat <EOL> from jinja2 . exceptions import TemplateAssertionError , TemplateSyntaxError <EOL> from jinja2 . utils import contextfunction , import_string , Markup , next <EOL> GETTEXT_FUNCTIONS = ( '<STR_LIT:_>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> class ExtensionRegistry ( type ) : <EOL> """<STR_LIT>""" <EOL> def __new__ ( cls , name , bases , d ) : <EOL> rv = type . __new__ ( cls , name , bases , d ) <EOL> rv . identifier = rv . __module__ + '<STR_LIT:.>' + rv . __name__ <EOL> return rv <EOL> class Extension ( object ) : <EOL> """<STR_LIT>""" <EOL> __metaclass__ = ExtensionRegistry <EOL> tags = set ( ) <EOL> priority = <NUM_LIT:100> <EOL> def __init__ ( self , environment ) : <EOL> self . environment = environment <EOL> def bind ( self , environment ) : <EOL> """<STR_LIT>""" <EOL> rv = object . __new__ ( self . __class__ ) <EOL> rv . __dict__ . update ( self . __dict__ ) <EOL> rv . environment = environment <EOL> return rv <EOL> def preprocess ( self , source , name , filename = None ) : <EOL> """<STR_LIT>""" <EOL> return source <EOL> def filter_stream ( self , stream ) : <EOL> """<STR_LIT>""" <EOL> return stream <EOL> def parse ( self , parser ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( ) <EOL> def attr ( self , name , lineno = None ) : <EOL> """<STR_LIT>""" <EOL> return nodes . ExtensionAttribute ( self . identifier , name , lineno = lineno ) <EOL> def call_method ( self , name , args = None , kwargs = None , dyn_args = None , <EOL> dyn_kwargs = None , lineno = None ) : <EOL> """<STR_LIT>""" <EOL> if args is None : <EOL> args = [ ] <EOL> if kwargs is None : <EOL> kwargs = [ ] <EOL> return nodes . Call ( self . attr ( name , lineno = lineno ) , args , kwargs , <EOL> dyn_args , dyn_kwargs , lineno = lineno ) <EOL> @ contextfunction <EOL> def _gettext_alias ( context , string ) : <EOL> return context . resolve ( '<STR_LIT>' ) ( string ) <EOL> class InternationalizationExtension ( Extension ) : <EOL> """<STR_LIT>""" <EOL> tags = set ( [ '<STR_LIT>' ] ) <EOL> def __init__ ( self , environment ) : <EOL> Extension . __init__ ( self , environment ) <EOL> environment . globals [ '<STR_LIT:_>' ] = _gettext_alias <EOL> environment . extend ( <EOL> install_gettext_translations = self . _install , <EOL> install_null_translations = self . _install_null , <EOL> uninstall_gettext_translations = self . _uninstall , <EOL> extract_translations = self . _extract <EOL> ) <EOL> def _install ( self , translations ) : <EOL> gettext = getattr ( translations , '<STR_LIT>' , None ) <EOL> if gettext is None : <EOL> gettext = translations . gettext <EOL> ngettext = getattr ( translations , '<STR_LIT>' , None ) <EOL> if ngettext is None : <EOL> ngettext = translations . ngettext <EOL> self . environment . globals . update ( gettext = gettext , ngettext = ngettext ) <EOL> def _install_null ( self ) : <EOL> self . environment . globals . update ( <EOL> gettext = lambda x : x , <EOL> ngettext = lambda s , p , n : ( n != <NUM_LIT:1> and ( p , ) or ( s , ) ) [ <NUM_LIT:0> ] <EOL> ) <EOL> def _uninstall ( self , translations ) : <EOL> for key in '<STR_LIT>' , '<STR_LIT>' : <EOL> self . environment . globals . pop ( key , None ) <EOL> def _extract ( self , source , gettext_functions = GETTEXT_FUNCTIONS ) : <EOL> if isinstance ( source , basestring ) : <EOL> source = self . environment . parse ( source ) <EOL> return extract_from_ast ( source , gettext_functions ) <EOL> def parse ( self , parser ) : <EOL> """<STR_LIT>""" <EOL> lineno = next ( parser . stream ) . lineno <EOL> plural_expr = None <EOL> variables = { } <EOL> while parser . stream . current . type != '<STR_LIT>' : <EOL> if variables : <EOL> parser . stream . expect ( '<STR_LIT>' ) <EOL> if parser . stream . skip_if ( '<STR_LIT>' ) : <EOL> break <EOL> name = parser . stream . expect ( '<STR_LIT:name>' ) <EOL> if name . value in variables : <EOL> parser . fail ( '<STR_LIT>' % <EOL> name . value , name . lineno , <EOL> exc = TemplateAssertionError ) <EOL> if parser . stream . current . type == '<STR_LIT>' : <EOL> next ( parser . stream ) <EOL> variables [ name . value ] = var = parser . parse_expression ( ) <EOL> else : <EOL> variables [ name . value ] = var = nodes . Name ( name . value , '<STR_LIT>' ) <EOL> if plural_expr is None : <EOL> plural_expr = var <EOL> parser . stream . expect ( '<STR_LIT>' ) <EOL> plural = plural_names = None <EOL> have_plural = False <EOL> referenced = set ( ) <EOL> singular_names , singular = self . _parse_block ( parser , True ) <EOL> if singular_names : <EOL> referenced . update ( singular_names ) <EOL> if plural_expr is None : <EOL> plural_expr = nodes . Name ( singular_names [ <NUM_LIT:0> ] , '<STR_LIT>' ) <EOL> if parser . stream . current . test ( '<STR_LIT>' ) : <EOL> have_plural = True <EOL> next ( parser . stream ) <EOL> if parser . stream . current . type != '<STR_LIT>' : <EOL> name = parser . stream . expect ( '<STR_LIT:name>' ) <EOL> if name . value not in variables : <EOL> parser . fail ( '<STR_LIT>' % <EOL> name . value , name . lineno , <EOL> exc = TemplateAssertionError ) <EOL> plural_expr = variables [ name . value ] <EOL> parser . stream . expect ( '<STR_LIT>' ) <EOL> plural_names , plural = self . _parse_block ( parser , False ) <EOL> next ( parser . stream ) <EOL> referenced . update ( plural_names ) <EOL> else : <EOL> next ( parser . stream ) <EOL> for var in referenced : <EOL> if var not in variables : <EOL> variables [ var ] = nodes . Name ( var , '<STR_LIT>' ) <EOL> if not referenced : <EOL> singular = singular . replace ( '<STR_LIT>' , '<STR_LIT:%>' ) <EOL> if plural : <EOL> plural = plural . replace ( '<STR_LIT>' , '<STR_LIT:%>' ) <EOL> if not have_plural : <EOL> plural_expr = None <EOL> elif plural_expr is None : <EOL> parser . fail ( '<STR_LIT>' , lineno ) <EOL> if variables : <EOL> variables = nodes . Dict ( [ nodes . Pair ( nodes . Const ( x , lineno = lineno ) , y ) <EOL> for x , y in variables . items ( ) ] ) <EOL> else : <EOL> variables = None <EOL> node = self . _make_node ( singular , plural , variables , plural_expr ) <EOL> node . set_lineno ( lineno ) <EOL> return node <EOL> def _parse_block ( self , parser , allow_pluralize ) : <EOL> """<STR_LIT>""" <EOL> referenced = [ ] <EOL> buf = [ ] <EOL> while <NUM_LIT:1> : <EOL> if parser . stream . current . type == '<STR_LIT:data>' : <EOL> buf . append ( parser . stream . current . value . replace ( '<STR_LIT:%>' , '<STR_LIT>' ) ) <EOL> next ( parser . stream ) <EOL> elif parser . stream . current . type == '<STR_LIT>' : <EOL> next ( parser . stream ) <EOL> name = parser . stream . expect ( '<STR_LIT:name>' ) . value <EOL> referenced . append ( name ) <EOL> buf . append ( '<STR_LIT>' % name ) <EOL> parser . stream . expect ( '<STR_LIT>' ) <EOL> elif parser . stream . current . type == '<STR_LIT>' : <EOL> next ( parser . stream ) <EOL> if parser . stream . current . test ( '<STR_LIT>' ) : <EOL> break <EOL> elif parser . stream . current . test ( '<STR_LIT>' ) : <EOL> if allow_pluralize : <EOL> break <EOL> parser . fail ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> parser . fail ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> elif parser . stream . eos : <EOL> parser . fail ( '<STR_LIT>' ) <EOL> else : <EOL> assert False , '<STR_LIT>' <EOL> return referenced , concat ( buf ) <EOL> def _make_node ( self , singular , plural , variables , plural_expr ) : <EOL> """<STR_LIT>""" <EOL> if plural_expr is None : <EOL> gettext = nodes . Name ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> node = nodes . Call ( gettext , [ nodes . Const ( singular ) ] , <EOL> [ ] , None , None ) <EOL> else : <EOL> ngettext = nodes . Name ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> node = nodes . Call ( ngettext , [ <EOL> nodes . Const ( singular ) , <EOL> nodes . Const ( plural ) , <EOL> plural_expr <EOL> ] , [ ] , None , None ) <EOL> if self . environment . autoescape : <EOL> node = nodes . MarkSafe ( node ) <EOL> if variables : <EOL> node = nodes . Mod ( node , variables ) <EOL> return nodes . Output ( [ node ] ) <EOL> class ExprStmtExtension ( Extension ) : <EOL> """<STR_LIT>""" <EOL> tags = set ( [ '<STR_LIT>' ] ) <EOL> def parse ( self , parser ) : <EOL> node = nodes . ExprStmt ( lineno = next ( parser . stream ) . lineno ) <EOL> node . node = parser . parse_tuple ( ) <EOL> return node <EOL> class LoopControlExtension ( Extension ) : <EOL> """<STR_LIT>""" <EOL> tags = set ( [ '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> def parse ( self , parser ) : <EOL> token = next ( parser . stream ) <EOL> if token . value == '<STR_LIT>' : <EOL> return nodes . Break ( lineno = token . lineno ) <EOL> return nodes . Continue ( lineno = token . lineno ) <EOL> class WithExtension ( Extension ) : <EOL> """<STR_LIT>""" <EOL> tags = set ( [ '<STR_LIT>' ] ) <EOL> def parse ( self , parser ) : <EOL> node = nodes . Scope ( lineno = next ( parser . stream ) . lineno ) <EOL> assignments = [ ] <EOL> while parser . stream . current . type != '<STR_LIT>' : <EOL> lineno = parser . stream . current . lineno <EOL> if assignments : <EOL> parser . stream . expect ( '<STR_LIT>' ) <EOL> target = parser . parse_assign_target ( ) <EOL> parser . stream . expect ( '<STR_LIT>' ) <EOL> expr = parser . parse_expression ( ) <EOL> assignments . append ( nodes . Assign ( target , expr , lineno = lineno ) ) <EOL> node . body = assignments + list ( parser . parse_statements ( ( '<STR_LIT>' , ) , <EOL> drop_needle = True ) ) <EOL> return node <EOL> class AutoEscapeExtension ( Extension ) : <EOL> """<STR_LIT>""" <EOL> tags = set ( [ '<STR_LIT>' ] ) <EOL> def parse ( self , parser ) : <EOL> node = nodes . ScopedEvalContextModifier ( lineno = next ( parser . stream ) . lineno ) <EOL> node . options = [ <EOL> nodes . Keyword ( '<STR_LIT>' , parser . parse_expression ( ) ) <EOL> ] <EOL> node . body = parser . parse_statements ( ( '<STR_LIT>' , ) , <EOL> drop_needle = True ) <EOL> return nodes . Scope ( [ node ] ) <EOL> def extract_from_ast ( node , gettext_functions = GETTEXT_FUNCTIONS , <EOL> babel_style = True ) : <EOL> """<STR_LIT>""" <EOL> for node in node . find_all ( nodes . Call ) : <EOL> if not isinstance ( node . node , nodes . Name ) or node . node . name not in gettext_functions : <EOL> continue <EOL> strings = [ ] <EOL> for arg in node . args : <EOL> if isinstance ( arg , nodes . Const ) and isinstance ( arg . value , basestring ) : <EOL> strings . append ( arg . value ) <EOL> else : <EOL> strings . append ( None ) <EOL> for arg in node . kwargs : <EOL> strings . append ( None ) <EOL> if node . dyn_args is not None : <EOL> strings . append ( None ) <EOL> if node . dyn_kwargs is not None : <EOL> strings . append ( None ) <EOL> if not babel_style : <EOL> strings = tuple ( x for x in strings if x is not None ) <EOL> if not strings : <EOL> continue <EOL> else : <EOL> if len ( strings ) == <NUM_LIT:1> : <EOL> strings = strings [ <NUM_LIT:0> ] <EOL> else : <EOL> strings = tuple ( strings ) <EOL> yield node . lineno , node . node . name , strings <EOL> class _CommentFinder ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , tokens , comment_tags ) : <EOL> self . tokens = tokens <EOL> self . comment_tags = comment_tags <EOL> self . offset = <NUM_LIT:0> <EOL> self . last_lineno = <NUM_LIT:0> <EOL> def find_backwards ( self , offset ) : <EOL> try : <EOL> for _ , token_type , token_value in reversed ( self . tokens [ self . offset : offset ] ) : <EOL> if token_type in ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> try : <EOL> prefix , comment = token_value . split ( None , <NUM_LIT:1> ) <EOL> except ValueError : <EOL> continue <EOL> if prefix in self . comment_tags : <EOL> return [ comment . rstrip ( ) ] <EOL> return [ ] <EOL> finally : <EOL> self . offset = offset <EOL> def find_comments ( self , lineno ) : <EOL> if not self . comment_tags or self . last_lineno > lineno : <EOL> return [ ] <EOL> for idx , ( token_lineno , _ , _ ) in enumerate ( self . tokens [ self . offset : ] ) : <EOL> if token_lineno > lineno : <EOL> return self . find_backwards ( self . offset + idx ) <EOL> return self . find_backwards ( len ( self . tokens ) ) <EOL> def babel_extract ( fileobj , keywords , comment_tags , options ) : <EOL> """<STR_LIT>""" <EOL> extensions = set ( ) <EOL> for extension in options . get ( '<STR_LIT>' , '<STR_LIT>' ) . split ( '<STR_LIT:U+002C>' ) : <EOL> extension = extension . strip ( ) <EOL> if not extension : <EOL> continue <EOL> extensions . add ( import_string ( extension ) ) <EOL> if InternationalizationExtension not in extensions : <EOL> extensions . add ( InternationalizationExtension ) <EOL> environment = get_spontaneous_environment ( <EOL> options . get ( '<STR_LIT>' , BLOCK_START_STRING ) , <EOL> options . get ( '<STR_LIT>' , BLOCK_END_STRING ) , <EOL> options . get ( '<STR_LIT>' , VARIABLE_START_STRING ) , <EOL> options . get ( '<STR_LIT>' , VARIABLE_END_STRING ) , <EOL> options . get ( '<STR_LIT>' , COMMENT_START_STRING ) , <EOL> options . get ( '<STR_LIT>' , COMMENT_END_STRING ) , <EOL> options . get ( '<STR_LIT>' ) or LINE_STATEMENT_PREFIX , <EOL> options . get ( '<STR_LIT>' ) or LINE_COMMENT_PREFIX , <EOL> str ( options . get ( '<STR_LIT>' , TRIM_BLOCKS ) ) . lower ( ) in ( '<STR_LIT:1>' , '<STR_LIT>' , '<STR_LIT:yes>' , '<STR_LIT:true>' ) , <EOL> NEWLINE_SEQUENCE , frozenset ( extensions ) , <EOL> True , Undefined , None , False , None , <NUM_LIT:0> , False , None <EOL> ) <EOL> source = fileobj . read ( ) . decode ( options . get ( '<STR_LIT>' , '<STR_LIT:utf-8>' ) ) <EOL> try : <EOL> node = environment . parse ( source ) <EOL> tokens = list ( environment . lex ( environment . preprocess ( source ) ) ) <EOL> except TemplateSyntaxError , e : <EOL> return <EOL> finder = _CommentFinder ( tokens , comment_tags ) <EOL> for lineno , func , message in extract_from_ast ( node , keywords ) : <EOL> yield lineno , func , message , finder . find_comments ( lineno ) <EOL> i18n = InternationalizationExtension <EOL> do = ExprStmtExtension <EOL> loopcontrols = LoopControlExtension <EOL> with_ = WithExtension <EOL> autoescape = AutoEscapeExtension </s>
