#NEWLINE# def find_variables( data , include_named = True ) : #NEWLINE# #INDENT# '\n  Finds all substitutable variables.\n\n  This uses Template.pattern, which is arguably\n  an implementation detail of string.Template.\n  ' #NEWLINE# found = set ( ) #NEWLINE# def f( val ) : #NEWLINE# #INDENT# if ( not isinstance ( val , basestring ) ) : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# for match in Template . pattern . finditer ( val ) : #NEWLINE# #INDENT# name = ( ( include_named and match . group ( 'named' ) ) or match . group ( 'braced' ) ) #NEWLINE# if ( name is not None ) : #NEWLINE# #INDENT# found . add ( name ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# recursive_walk ( f , data ) #NEWLINE# return found